Authentication with basicHttpBinding - wcf

I have converted my webservice to wcf service keeping the extension of wcf service as asmx since I have a large client base and do not want to ask users to change the extension. Currently I have username / pwd authentication for my clients which I want them to move out of. Since my user base calls my web service from all sorts of machines and OS's, I am not able to get what type of authentication I can move them to.
X509 Certificate, issued tokens, username pwd or something else..? Any help or guidance with some sample code blocks or urls' would be appreciated.

If you are replacing ASMX service with WCF service you are using BasicHttpBinding (and perhaps also AspNetCompatibility). In that case you don't have many choices. You can use Transport security (HTTPS) with client certificates or TransportWithMessageSecurity (HTTPS + UserName token profile). If you don't want to use HTTPS and you still want to use UserName token profile you need .NET 4.0 and you have to create custom binding like:
<customBinding>
<binding name="InsecureCredentials">
<security mode="UserNameOverTransport" allowInsecureTransport="true" />
<textMessageEncoding messageVersion="Soap11" />
<httpTransport />
</binding>
</customBinding>

Ultimately, it depends on whose doing the calling for to your service, IMO.
If this is primarily B-to-B, meaning that your clients are some automated process rather than, say, a silverlight app, I'd prefer identity certs (i.e. x509). If this is a user-driven call such as a silverlight app, then I'd stick with username/password, but consider federated identity.
That said, given the fact that you have many different types of clients, even if it's b-to-b there's no guarantee you'll be able to service every client with x509. In my experience, too many shops just aren't flexible enough to adopt "newer" standards (even though x509 has been around a long time, it's still "new" to a lot of people making web service calls). Therefore, it might be best for you to stick with username/password.
You could offer all three, however. WCF is very very nice that way; it's quite simple to set up a single service implementation that just happens support either username/password auth or x509 or federated identity. Almost all of that is handled by the binding configuration; you might need some plugin code for the username/password auth (depending on how you're set up) but the auth code is completely divorced from the service code.

Related

WCF security with load balancer

We need to create a WCF service (.NET 4.0) that will be consumed by a client outside of our organization.
The case is that we have two servers that are behind a load balancer which terminates the SSL. This is where it gets confusing for me.
How we could and should handle the authentication?
The previous experience about WCF is only about services for internal use. If I understood correctly we should use basicHttpBinding to guarantee interoperability with Java based client. I don't know if this is an issue with JAX-WS based client.
There will only be this one client that is going to use the service.
We need to somehow ensure that caller is authenticated to use the
system
Make sure the message is encrypted when moving in public network
So far the best article that I found was
http://devproconnections.com/net-framework/wcf-and-ssl-processing-load-balancers
There were few suggestions how to do this.
WCF services can be configured for basic authentication and receive credentials in the clear over HTTP. This can work; however, it precludes passing credentials in the message, and the use of more interesting credentials (such as issued tokens).
We use forms authentication on our website under which the service will be hosted. I think it is not easy or even possible to make the service then use basic authentication.
WCF services can be configured to fake the presence of transport security so that the runtime will allow receiving message credentials without transport or message protection
Will this be the way to go and will this work with basicHttpBinding?
The client and server binding will be different. The client binding will use username auth in eitehr message or transport level with transport security (ssl):
<bindings>
<basicHttpBinding>
<binding name="NewBinding0">
<security mode="Message" />
</binding>
</basicHttpBinding>
</bindings>
then the server config will use the same config but without the transport security. If you chose to use message security then check out WCF ClearUsernameBinding. If you use trasnport security (basic http) then set mode="TransportCredentialOnly".

How to do authentication on a WCF 4 RESTful service?

I'm currently designing and developing a WCF 4 RESTful service that will be used by mobile devices. I specifically picked REST because it's supposedly lightweight and the JSON output makes parsing simple for the mobile clients.
The service takes care of the mobile devices part of the entire application. But, it requires that users log in before using the service. Basic HTTP authentication is not an option: It's insecure and a man-in-the-middle attack could easily intercept the user accounts. SSL is an option here, but I have no idea how easily SSL works on a WCF RESTful service and how simple it is to implement on mobile devices.
I've looked into Digest Authentication, but I can't really find any good information on how to implement it. And that also brings up: How am I going to allow users to add a device to their account with this? Hash the username/password combination into the Digest header along with other information?
Could someone shed some light on this? Because I'm confused as hell. There is plenty of information on the net on how to implement WCF (RESTful) services, but the moment you need to secure it, the amount of information drops significantly... Articles are welcome.
Leveraging SSL is brain dead simple in WCF and should be supported by every mobile platform at this point. You should defintiely go basic auth with SSL to keep your life as simple as possible IMHO.
All you need to do to enable HTTPS on your WCF service is:
<webHttpBinding>
<binding name="MyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</webHttpBinding>
That will say "only allow access to this service over a secure transport and expect a basic auth credential to be passed".
Now, the only question is, where are you hosting your WCF service? If hosting in IIS you need simply need to configure the service certificate with it and you're all set.
Another option is to do SSL up front with an F5 device or something like that. Then you have to do a little more work because, by default, WCF will not let you pass crendentials over a non-secured transport. Then you need to get into customizing your own binding and setting the AllowInsecureTransport = true on the TransportSecurityBindingElement. This will basically say "trust me, I'm doing the right thing" to WCF and allow the service to initialize propertly even though the credential will flow over a non-secure binding.

Authentication settings in IIS Manager versus web.config versus system.serviceModel

I have a WCF web service, and I want to use Basic authentication. I am getting lost in the authentication options:
In IIS 6 Manager, I can go in to the properties of the web site and set authentication options.
In the web site's web.config file, under system.web, there is an <authentication mode="Windows"/> tag
In the web site's web.config file, under system.serviceModel, I can configure:
<wsHttpBinding>
<binding name="MyBinding">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</wsHttpBinding>
What is the difference between these three? How should each be configured?
Some context: I have a simple web site project that contains a single .svc web service, and I want it to use Basic authentication over SSL. (Also, I want it to not use Windows accounts, but maybe that is another question.)
The first two are really about access to an ASP.NET virtual directory or virtual application in IIS6 - that has basically nothing to do with WCF (WCF is actually not part nor dependent on ASP.NET). The settings control how the HTTP request coming into the IIS6 web server is being handled in terms of authentication. This basically controls whether anonymous callers from the internet can just call in without authenticating, or whether they need to enter username/password, or whether only callers with a valid Windows identity in this domain are allowed in.
The only reason this is interesting to your WCF service is the fact that when you host the WCF service in IIS (only one of the many options), then you have a (myservice).svc file that needs to reside inside a virtual directory. Of course, access to that SVC file is controlled by the authentication settings of IIS6/ASP.NET.
The security mode inside the <wsHttpBinding> section is the security-related definition of how the WCF service will communicate with its clients. Mode=Transport means, you're securing the actual transport layer - typically using SSL - not each message separately. This setting works great in Intranet scenarios where you have all clients behind a corporate firewall - but it won't work too well in Internet scenarios, since you can't really control the whole chain from the client (anywhere on this planet) over a series of intermediary hops to your server - you just can't. In this case, you'd have to use Mode=Message which basically encrypts and signs each message that goes over the wires - that works over any number of routers and relays along the way from the point of origin to your server.
The first two are related, if they don't match your service will not be able to activate. If you choose Windows authentication obviously there is an assumption that you will be tied to a windows domain or local machine.
Since you are going to be doing SSL basic authentication you are going to set this to None and then configure your transport security.
Your one stop shop for setting up transport + basic authentication
MSDN Article on Transport+Username + Windows Forms
I am not sure if you are still planning out how you are going to be doing security but i would recommend thinking about using message security versus transport(personal bias toward message security)..
Transport vs Message Comparison
Patterns & Practices on Message and Transport Security

WCF - Configuring Client/server authentication in headers?

I've got a WCF service that will need to receive client credentials, and maintain some kind of role-based data, based on my auth method.
The clients will reside on many different systems, and as such, each client will have a unique userID and pw.
I'm using basicHttpBinding and have read a few articles, such as this one,
http://nirajrules.wordpress.com/2009/05/22/username-over-https-custombinding-with-wcf%E2%80%99s-channelfactory-interface/, that describe the process.
So what I'm looking for is if someone has a full client/server configured like this to take a look at so I can derive my own solution from this.
What I'd like to do is have the username and password passed in the headers for each request, passing back some kind of SecurityTokenValidationException on fail, or continuing if passing.
Thanks.
UPDATE
I'm using the wsHttpbinding with the following config on both the client and server:
<wsHttpBinding>
<binding name="wsHttpEndpointBinding" >
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic" />
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
And the call out to the server from the client as follows:
ServiceReference1.ServiceClient myClient = new ServiceReference1.ServiceClient();
myClient.ClientCredentials.UserName.UserName = "billuser";
myClient.ClientCredentials.UserName.Password = "mypassword";
Response.Write("Data from WCF Service: " + myClient.GetData(1));
I think I need a bit of a hand with linking up the CustomUsernamePasswordValidator on the server as I'm still getting the '...could not be activated.' error.
Are you required to use the basicHttpBinding? That binding is really only there to provide support for legacy WS-BasicProfile implementations (i.e. ASMX). If your clients are also .NET/WCF, I would highly recommend using wsHttpBinding, which provides a plethora of security options out of the box. You could use certificates, username/password, etc. with transport and/or message security and not need to write any of the security stuff yourself. Just configure-and-go (CAG).
Security credential information is available to the service itself via the OperationContext, in case you need to access it directly from your code. If your code does need to access it, however, I would recommend writing a behavior to extract the pertinent information from the OperationContext and place it in something more application specific so that you don't have to reference System.ServiceModel everywhere you need to access information on OperationContext.

How to configure security when calling WCF Service from .Net 2.0 Client

I have a WCF service up and running and am able to communicate between the service and a .Net 2.0 Client using basicHttpBinding.
I now need to lock down the WCF service so that it can only be called by authenticated clients.
I have control over the clients that will be calling my service. The clients are part of a product that will be installed in the wild and "phoning home" to push and pull data. The client app is written for .Net 2.0 framework and cannot be upgraded to 3.0 or 3.5 at this time. I cannot add windows user accounts to the client machines.
What are my options for securing the WCF Service and being able to authenticate from my .Net 2.0 clients? Also, data needs to be passed over https.
I've been searching the web, and feel like I'm on a wild goose chase.
You can configure a WCF endpoint to use 2-way SSL authentication. That means that you can require clients to present an X.509 certificate that confirms their identity whenever they make a request to the service.
On the server side of things, you can use one of the built-in validation schemes in WCF or provide your own validation logic to check the X.509 certificate.
If you were hosting your service in IIS, it would be trivial to configure SSL to require client certificates at the transport-level. However, you can find a good guide on how to implement this behaviour in a self-hosted WCF service here:
http://leastprivilege.com/2007/08/25/certificate-based-authentication-and-wcf-message-security/
I haven't tried this myself but, since this creates a security requirement at the message-level, I think you will have to use wsHttpBinding to enforce it in your WSDL contract, since imposing security requirements to access a web service is part of the WS-* standards.
If you have to use basicHttpBinding, you can try this solution instead that moves things up at the transport-level:
http://leastprivilege.com/2007/08/26/certificate-based-authentication-and-wcf-mode-independent/
Hope this helps
OK so, with SSL you have transport level security; which is fine, that protects the message from sniffing and changing.
So now you have options; do you need the validation to be silent, or can you prompt the user for a username/password when your program starts? If it must be silent then you can go the client side certificate as mentioned (although that is painful, you will need to generate the certificates yourself and validate them, so you need to look at running your own certificate authority). Or you can embed a custom header in the message which contains a client ID and do it the kludgey way.
If however you can prompt for a username and password then you authenticate that way and plug it into a database lookup quite easily using a custom authenticator, or even using the ASP.NET membership database.
Here is what I ended up doing which seemed to be the simplest solution in our situation, which is pretty small scale with only a handful of web services exposed:
Secured the transport with SSL
Clients first login to the web service by calling a Login method on the web service. If the login succeeds, it returns an encrypted FormsAuthenticationTicket to the client.
Clients must then supply the forms authentication ticket with each web service call. Each method checks if the ticket is valid and if so it does its work. If the ticket has expired or is invalid, clients must re-authenticate.
Hope that helps someone...
You security will be covered by the ssl.
For authentication you have two options - basic (username and password) or certificate.
Here is a video that demonstrates configuring certificate authentication.
In that you are configuring the security elements of the basicHttpBinding shown below:
<basicHttpBinding>
<binding name="basicHttp">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
There is also a good page on this here. Google on clientCredentialType and you should find yourself on the right track soon enough.
For setting up the client certificates you are after the wse* policy file.
You will need to work out how you will provide the client certificate to the various sites.- that depends on security concerns of the project. There are various ways (none of which I can remember sorry, I last did this for wse* to wse* about two years ago so the details are forgotten, but it is certainly possible, took a few days solid research to find a good method).
Using SSL certificate is the only option for .NET 2.0 client accessing WCF service as basicHttpBinding provides no security. By using SSL, you are securing the whole transport channel.
Check the link http://www.codeplex.com/WCFSecurityGuide/Release/ProjectReleases.aspx?ReleaseId=15892 . It covers WCF Security covering all scenarios.
To get free SSL certificate please visit http://www.comodo.com/ or http://www.instantssl.com/ and try out in your application.