Reputation: 7722
We have a C# client app that communicates to our C# backend service via WCF. We want to make sure that each WCF call made to our service is from a user that has logged into our client and not via some hacker who has figured out how to call our WCF services.
I suppose there are several ways we could ensure this. One of which is to have our backend Login method return some sort of token that each client WCF call must then pass as part of the WCF call. In order to get such a token, the caller would have to provide valid login credentials. For each WCF call then, the token would get validated on the backside. If the token cannot be validated, the WCF call fails.
I'd like a simple straightforward way of doing this. We don't need anything super complex and secure. Anyone have any information on the standard way of accomplishing this? We're using .NET 4. I should add that I don't have a great deal of experience with WCF.
A little more information. We have two different client apps calling our WCF services. One is a WPF based client and the other is a browser based app (ASP.NET). Both are internet wide applications. Our clients could be anywhere in the world.
Upvotes: 1
Views: 10444
Reputation: 364409
The easiest way to implement this is using wsHttpBinding
with this configuration:
<bindings>
<wsHtttpBinding>
<binding name="securitySession">
<security mode="Message">
<message clientCredentialType="UserName"
establishSecurityContext="true"
negotiateServiceCredentials="false" />
</security>
</binding>
</wsHttpBinding>
</binding>
This binding configures state full service with security session. If your clients create proxy for the service it must pass user name and password in initial security handshake performed internally. During this handshake WCF creates service instance which is associated with security token. Security token is passed back to client proxy and the proxy stores it internally. Any subsequent calls from the same proxy instance contains this token which authenticates them and pairs them with correct service instance.
To make this configuration work in custom environment you must configure your service to use certificate which will secure communication (otherwise anybody can intercept communication and steel user name and password or token). You must also use custom user name and password validator (or ASP.NET membership) on service side.
How does it fit to your solution?
Your ASP.NET application can use custom form authentication using the service for starting security session. On ASP.NET side you will need to keep the proxy in ASP.NET session and timeouts for both security and ASP.NET session will have to be correctly configured so that ASP.NET session expires prior to WCF security session. You will use cookie to receive correct ASP.NET session for subsequent client calls.
In your WPF application you can either use same approach and store proxy per application run. You just have to make sure that proxy will not timeout or handle the timeout and log in user again. Client machines will also have to trust certificate used by your service.
In case of WPF you can also avoid security session and expose second endpoint on your service with establishSecurityContext="false"
. In this case user name and password will be included in every call from WPF application and you will not have to fight with many problems associated with long living proxy using state full service. Without security context service for your WPF application will be state less. The reason why you don't want to use this with ASP.NET is that you will have to store user name and password in session.
What are disadvantages of this solution?
This is heavy weight solution. Security context provides functionality you are looking for without any coding at your side but it has its own cost. You will have to use session in ASP.NET application to maintain WCF proxy, you will have state full service which is something you should usually avoid and you will have to do a lot of performance and memory tweaking if you expect heavy load in your application. You will have to control that sessions are correctly released and that all WCF proxies are correctly closed and disposed so that service instances are released as well. You will have to play with throttling in WCF to support enough concurrently running service instances.
I successfully used similar approach in internet facing web application with heavy load 4 years ago but it took us some time to find all issues and correctly configure all timeouts and correctly handle releasing of all objects.
As alternative you can look for some federated scenario where you will have one additional service handling authentication and providing security token which would be used to authenticate to your ASP.NET application and to your WCF service. I think OAuth should handle this scenario as well.
Upvotes: 1
Reputation: 3230
I suggest you use wsHttpBinding with certificate-based message security. Take a look at the walkthrough here: http://www.codeproject.com/Articles/28248/Securing-WCF-Services-with-Certificates (it is for Windows Server 2003 but the procedure is not much different on newer servers)
Upvotes: 0