Add a request header from the url, to support multi-tenancy - web-services

Background
I have an existing service contract which cannot be modified. The implementation of the service is code which I support and can change.
Currently, the service supports a single tenant, and multiple instances of this service are hosted, for example http://foo-tenant1.com/service.svc and http://foo-tenant2.com/service.svc
Now I want to change the service to support multiple tenants, with a single service. For example, the service hosted at address: http://foo.com/service.svc and support for multiple tenants by adding a tenant id to the address;
for example:
If WCF can somehow support wildcard routing:
http://foo.com/tenant1/service.svc and http://foo.com/tenant2/service.svc etc...
or if it can somehow support query strings:
http://foo.com/service.svc?tenant1 and http://foo.com/service.svc?tenant2 etc...
or some other way...
The reason for this is that the clients calling this will not have any concept of a tenant. From the client's perspective there is only a Url for each tenant.
Question
How can I host a WCF service with a "catch all" endpoint like this? Or can I do this with routing or url rewriting? I can then get the tenant Id into a request header, and modify the service code to support multi-tenants.
I can then change the service code to read from the request header and support the tenant Id.

If you don't have access to the code for the service or can't change the code, you'll need to think a little outside the box. One option would be to create separate applications inside IIS and hopefully your service allows you to change web.config values such that you can configure the service to look at a different database (if that's what is backing it).
But if the web.config route doesn't capture all of your variables, you might have to think about doing an IHttpModule. Injecting that early enough in the service stack would give you options to do what you will with the URL, though you still don't have control over the code that subsequently gets called unless you completely override what gets called and don't call the base method to continue execution.
You could also write a page for 404's that you have control over the backing code such that you can then do something dynamically at that point. You would just need to modify the web.config file to point 404's to the URL and execute it. Though be warned, that is all 404s.
Finally, if the code that implements the service contract can be removed, you could drop a DLL onto the server that implements the contract and update the web.config file to point to this DLL instead. Though this might not be possible if the DLL that you remove also removes a significant portion of other code.
If you don't have access to the code, you are going to have a tough time as all of these solutions are pretty advanced concepts.

Related

How to define URLs only once for server and client?

everyone! I am building a web application, i.e. a server-client application. For the interaction between the two, I have to define the URLs twice (hard-coded strings), both on the backend and the frontend, which makes future changes hard, because it would require changing the code in two places, rather than just one.
I am using Django and Angular and so I am looking for a way to specify the back end endpoints once, then ideally read them and use them for the Angular production build. Therefore changes to the endpoints will only require a new build, but no further changes.
Should these be defined in some .cfg file and be read by the back end on server startup and maybe somehow add them to the Angular's build process? Any suggestion would help because this redundancy comes in almost every webapp project and there has to be a more clever solution!
Thanks for the help in advance!
Here, it is the backend application that owns and defines url mappings to entities. It is possible that multiple clients can consume from the same API, like a web client, an Android client and an iOS client. In this setup, your backend is the point of truth for the url mappings, and client applications should be configured to use the url mappings defined in the backend application.
One possible way to do this is to serve defined urls in the backend on a path of the backend application, and have your client applications configure themselves using the data provided there. For example, if you use Django Rest Framework, by default, on the root path of the API ("/"), resources along with url mappings for the resources are served. You can use such a mechanism to configure your client applications on build time.
How many endpoints and how likely are you to alter them? Most likely you will always have to make more changes than just in 1 place as the reason behind changing an endpoint is normally you are trying to POST or GET new data structures. This would mean you will have to alter that request process anyway to handle the new data type or what was being posted.
Also, consider some of the publicly available api's out there - they don't give you an endpoint that serves a config file of available routes. When they make a change to their endpoints they usually create a versioned api so that consumers can upgrade in their own time.
In my opinion, unless you are planning a large scale web app, I wouldn't be too worried about trying to implement something like this.

Can I generate a wsdl file without binding and service information?

I came across an issue where a customer is able to open a SAP wsdl using net-beans as well as in .Net but not in soap UI.
When i checked the wsdl i found that service as well as binding tags are not defined or no such tags included. wsdl ends with port-type information.
In soap UI i got an error like no content in the file and when i try to open it in eclipse i am able to open it using web explorer window, but service as well binding information fields are empty. I could see ws-policy elements in customers wsdl.
How he might have produced a wsdl without binding and service information ?
What would be the reason he is telling it is working in .Net?
I am not sure about .Net tools.
Is there any web service client tool which can open the operations without endpoint /service information and send request/response ?..
please help
thank you for your time.
I only know a bit about the first question, can't help you with the other ones...
You can request two "flavors" of WSDL from a NW/ABAP system. This is related to the fact that the implementation (programming) of the service is usually performed on a different system and by different people than the configuration of the service.
After the service (or rather a service definition) has been implemented, you can get what's called a "design-time WSDL document". This document does not include the endpoint information - it cannot, because that would require technical information about the target system landscape and its configuration that is simply not available yet.
From the service definition, an administrator can create a configuration. This includes the binding information as well as stuff like base URL, security settings, transport layer settings and so on. With this configuration, you can generate a second WSDL document that contains the actual endpoint configuration.

webservice authentication and user identity management

My team and me are currently working on quite a large project. We are working on an online game, which will be accessible (for the moment), in two ways:
-Via a web browser, an application full JavaScript(client-side), full Ajax (basically meaning that the UI will be managed in JS client side).
-Via an iPhone application (the UI will be managed by the application itself).
Between the two different applications, the core logic remains the same, so I believe (I could be wrong), that the best solution would be to create a web service (if possible using standards such as RESTful or Rest) capable of perming all necessary operations.
Following this logic, I have encountered a problem: the authentication and identity management of the user. This poses problem as the applications users need to be authenticated to preform certain operations.
I’ve looked into WS-security, but this obviously requires passwords to be stored, unencrypted on the server, which is not acceptable!
I then looked into Oauth, but at first glance this seemed like a lot of work to set up and not particularly suited to my needs (the way that applications have to be accepted does not please me since it will be my application and my application only using the web service, not any external application).
I’ve read and heard about a lot of other ways to do what I want, but to be honest, I’m a little confused and I don’t know what information is reliable and what isn’t.
I would like to note that I’m using symfony2 for the backend and jquery for the client side JavaScript.
Furthermore, I would like a detailed, step-by-step response, because I really am confused with all that I have read and heard.
Thank you for your time, and I hope someone can help me as it’s quite urgent.
Good evening
I'm not entirely sure if this answers your request, but since the UI will always be handled on the client side, I think you could use stateless HTTP authentication:
This is the firewall in security.yml:
security:
firewalls:
api:
pattern: ^/api/ # or whatever path you want
http_basic: ~
stateless: true
And then the idea basically is that on the server, you use your normal user providers, encoders and whatnot to achieve maximal security, and on the client, you send the HTTP authentication headers, for example, in jQuery:
$.ajax("...", {
username: "Foo",
password: "bar"
});
Please note that since the authentication is stateless (no cookie is ever created), the headers have to be sent with every request, but, I figure, since the application is almost entirely client-side, this isn't a problem.
You can also check the Symfony2 security manual for further information on how to setup HTTP authentication. Also be sure to force HTTPS access in your ACL, so the requests containing the credentials are secured (requires_channel: https in your ACL definitions).

Connect to different servers offering the same web service with WSDL

I'm entirely new to web services and all I've been able to do is a Hello World
My situation is the following, I have some servers which provide a WSDL file, all the servers provide the same file and methods, they just have different IPs/ports. In addition each server contains its own set of users.
I know how to communicate to work with one WSDL at a time, but I need 2 things:
Being able to add web services dynamically (connect/disconnect to other servers)
Being able to perform methods on the right server as the right user (you cant make a request if your user does not exist on the server you are asking to)
I have no idea of where to start, can someone point me in a direction to solve those 2 problems?
You're not specific in terms of libraries you use.
For example if you use CXF (Jax-WS in general) you can do the following:
// change endpoint URL
((BindingProvider)service).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "new url");
// new username. password will be provided by WS callback
((BindingProvider)service).getRequestContext().put(SecurityConstants.USERNAME, "username");
If you're using Spring for the infrastructure you can autowire all proxies with one statement:
#Autowired
private Map<String, ServiceInterface> interfaces;
If you want to add web services dynamically you have to decide whether this dynamically means at any time or at application startup - this however has nothing to do with web services - it's general programming model of autodiscovery (you can use database, one single remote source of available services, etc.)

How to do SSO between two web services in intranet?

The two web service(rest) are running on separated JVM instances with its own authentication.
The services is used by external user's log in, the server2 is for customer service team. After external use log in, he can call server2 for query. Oppositely, after customer service guy log in server2, he also can call server1 to change external user profile.
In another word, these two services trust each other. It seems like a SSO between them. Since both of them run on internal environment, I am wondering if there is a simple solution to implement it.
Thanks
I've had a good experience with JOSSO:
The setup is relatively simple (gateway and partner applications)
Non intrusive (no big changes needed for your application to work with it)
Based on JAAS
Supports various stores (LDAP, XML, DB...)
Works with Java, PHP and ASP (we use Java and PHP at our company and it works flawlessly)
You've got a lot of different options:
You could roll your own authentication system. It'd be exactly what you need, but you get to debug it yourself.
You could deploy Kerberos. A little old-school, but it clearly differentiates login servers from trusting servers.
If you're already in an MS-heavy environment, Active Directory might be just the tool.
OpenID is the new kid on the block; as used by StackOverflow :) but implementations of servers and clients might be harder to find.
LDAP is an easy way to get site-wide directory services; actually doing authentication against it might be a bit more work. (Which is why Active Directory is as popular as it is -- combining LDAP with Kerberos into one mechanism for site-wide authentication and authorization. Neat.)