For an enterprise type WCF service, where potentially 10K's of thousands of clients will be authenticating and sending data to central servers, what is 'best' practice when it comes to sessions or authentication?
does WCF support a session, if yes, should I use it?
or should I simply pass username/password on a per call basis?
As blowdart mentioned, WCF Sessions are not the same as ASP.NET Sessions. You can read up on them here: http://msdn.microsoft.com/en-us/library/ms733040.aspx. Before you roll your own security, you'll want to get familiar with what WCF gives you out-of-the-box: http://msdn.microsoft.com/en-us/library/ms734736.aspx. They may get you close to your goal without writing a lot of code. Specifically, check out How to: Create a Secure Session. With secure sessions, the Client and Server cache credentials so you don't have to fully authenticate with each request. By default, you'll lose a secure session if the web server recycles. If you want a secure session that lasts through a recycle, you'll want to look at How to: Create a Stateful Security Context Token for a Secure Session.
WCF does support sessions yes; but they are not like ASP.NET sessions. Sessions are there to deliver messages in order (and other bits and bobs), they are not there to add shared storage between calls.
For authenticated service calls you should send your authentication details every time; security is applied on a per message basis.
If you host the service within IIS, you can still use the session that is from ASP.NET
by enabling aspnetcompatibility for the service behaviour.
Related
I'm currently using Thinktecture's Identity Server as a security token service to handle the issuing of tokens based on username and password claims. This fits perfectly for a scenario where the authenticating client is an actual user authenticating against a web application for instance, but I'm now interested in scenario for when the authenticating party happens to be an independent process on the server that needs to establish a security token to pass to another server process. I'm ideally after a few pieces of advice here:
1. Is this a valid approach to authentication for server processes communicating with each other?
2. What if I were to move one of the server processes to a different machine talking across a TCP boundary instead perhaps? Is this approach still valid.
3. What ClaimTypes would I use for authentication of the process? And is the Thinktecture Identity Server happy to authenticate against these? I assume I'll probably have to write a custom authentication extension to it to do so...
Thanks very much,
Clint.
One of IdentityServer's authentication protocols is the "simple http" -- you pass in credentials and get back a token. This might be what you want.
Oh, there's also the WS-Trust endpoints as well.
I've been using wcf for a while and its authentication mechanisms, Windows, UserName/Password, Client certificate for a while.
I'd like to better understand how WCF uses these authentication mechanisms internally when creating SOAP messages and sending them.
Specifically, are the authentication credentials passed by wcf in every SOAP request, or does it only pass the authentication credentials in the first request and then some kind of token is issued and passed back and forth during subsequent sessions?
Are these authentication credentials (username+password, windows, client certificate) passed in a different manner depending on whether the security mode is transport or message? Is it that in message mode, the authentication credentials are inside the SOAP message, while in the transfer mode, http headers are other transport protocol specific are used to pass the authentication credentials?
Lets just assume that the SOAP message is secured using https when Transport mode is used and encrypted when using Message Mode and not worry about message privacy or tampering for this question.
You've asked several big qeustions, but I'll try to answer the question about sessions.
Session and authentication handling depend on the binding you're using. If you're using basichttpbinding, for instance, the host basically acts like a web server and no persistant "sessions" are created; as a result each SOAP request you send must contain everything necessary for authentication on the host. However, there are some bindings available like WSHTTPBinding that allow for the creation of security and reliability sessions that persist after the initial authentication using a token.
Wrapping the message in SSL should prevent problems.
I am currently following this scenario
Instead of a Windows Forms client, I have an ASP.NET MVC web app.
I am a little worried about the sending of the username and the password
on every call to the Web Service.
That means I will have to carry this information all the time in the session.
Wouldn't that be little security problem ?
Why would you have to carry the credentials all the time in the session? According to the example you're following, they're being set in the proxy (when it's created).
If you're worried about having to cache the credentials for recreating the proxy as needed, then you can cache an instance of ChannelFactory, and then generate new proxies from that instance as needed.
Regardless of what path yout take, the credentials are going to have to be stored somewhere, somehow, unless your application prompts the user for their credentials for every WCF operation.
You can implement WS-Security in your service.
This means you can send user credentials in the header of the message encrypted. Lots of examples out there for this.
I am working with WCF Webhttp services. I have created a bunch of services and all that remains is to put in user authentication...
Questions
Keeping with the rest architecture style, should I authenticate each service call against the user db.
If so, I should just do authentication by supplying the credentials and password each time the service is called and make it secure with SSL. Basically, each webget/webinvoke function should contain the user credentials as parameters and I authenticate each call. Is this right? This seems rather inefficient.
Using session key somehow seems wrong but any pointers as to how to use Session in WCF Webhttp?
I am not working with ASP .net membership (will be looking into it soon) since I was working with Mysql and have my own registration/user database created. Should I be looking at that? Can I use a wcf authentication service along with wcf webhttp services?
Any literature on handling authentication in WCF webhttp services would be greatly helpful.
Many thanks
You can check Chapter 8 of RESTful .NET book (Amazon, Google books)
You will authenticate only the first call from the user, any subsequent calls will use the context of the authenticated user. There are several options how you can use SSL(TLS), like always or just when you send username/password.
I am not sure where exactly and how you store the authentication token (like in Session or similar type).
You don't need to use ASP.NET membership provider, in fact you may not use any membership provider at all, just use other authentication models. Usually, there will be only one authentication model per service, like you get the credentials, check them against persisted storage, if valid you set the security token and that token is used for all the next calls for a limited amount of time.
I'm rather new to SOA and therefore experimenting around.
Currently, the part that creates the biggest problem to me is authentication, my current thought about it involves the following:
The client sends some kind of authentication message to the authentication / user service, this service queries the db and if the user is found and the password is valid, it will respond with a session id, this id will be used in all further requests of this client.
This seems rather ok to me but I don't know how I should handle the requests to other services, I thought of three different approaches.
Every service asks the authentication service if the session is valid and if so, what roles the user is in. The authentication service looks in the db and replies accordingly.
The authentication service keeps all session information in ram and responds without the db roundtrip to the requests.
The authentication service sends an authorized message to an esb, the esb forwards this authorized message to every service and these services cache it. No further requests to the authentication service would be necessary. If the user logs out or his roles change, another message would be send around and processed by all services.
I think the first approach creates too much stress on the authentication service / db but takes the least effort to implement.
The second is still very easy to implement but the stress on the authentication service remains almost the same.
The third is a little more complicated to implement but would has reduced response time as no trips to the authentication service take place. Though, if there are too much session information this approach would just fail and scalability is hardly given.
The best approach should be like this if all the services are internal,
The authentication service issues a token the the service client.
Service client includes the token in the SOA message wrapped in WS-Security or something similar.
The service should validate the token with authentication service before providing the service.
For external services, I suggest you look at federated solutions like SAML.
Don't do premature optimization. Your option no. 3 which you acknowledge will be more complicated to implement is unnecessary. Choose option no. 2 if that's what you can implement fast. You can profile later and change it, but I'd bet money that you won't have a 'bottleneck' when going with option 2.