views:

4450

answers:

3

I am refactoring a working ASP.NET Web Application to expose Web Services interface using ASP.NET Web Service. According to Web Services authentication - best practices, Basic Auth over https is the way to go. Let's assume it is, as opposed to doing WS-Security, X509, etc..

On .NET 3.5/VS 2008, what's the simplest way of implementing custom http Basic Authentication (non-Windows account), for example, accepting only if user name is "foo" and password is "bar". Ultimately, I'd like Thread.CurrentPrincipal set.

Do I write my own HttpModule or can this be done simpler?

+1  A: 

If you are considering WCF, you can use usernameOverTransport security for basicHttpBinding. i.e. username and passowrd reside in the SOAP header of the request and all the traffic are protected by SSL encryption over the wire.

A custom UserNamePasswordValidator validator can be used to authenticate the incoming credentials against e.g. database.

You can set the thread principal within a custom IAuthorizationPolicy in the service behavior.

e.g. Evaluate method implementation for IAuthorizationPolicy for setting current principal

public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
       Object obj;
       if( evaluationContext.Properties.TryGetValue( "Identities", out obj ))
       {
            // get the authenticated identity
            IIdentity client = (obj as IList<IIdentity>)[0];
            evaluationContext.Properties["Principal"] = ... // create principal obj here for the identity
            // this will set thread's current principal
       }
       return true;
}
codemeit
I want user and password in http header, not SOAP header. Also username over transport doesn't work on IIS: http://www.leastprivilege.com/WCFUsernamesOverTransportAndIISHosting.aspx
eed3si9n
usernameOverTransport for basicHttpBinding definitely works even hosted in IIS, i have solution deployed to production a while ago. bear in mind that it is not basic auth that configured in IIS. it is at soap message level.
codemeit
A: 

Grab the value of the Authorization header, parse it and validate the username/password.

The value is username:password, encoded as a Base64 string.

See http://en.wikipedia.org/wiki/Basic_access_authentication for details.

Edit: if you want this done for every request, using the custom auth scheme, then it would be easier to write an HttpModule to handle parsing the header and setting the thread's principal.

Brannon
+2  A: 

Likely using Custom Basic Authentication for IIS, written by Dominick Baier is the way to go. As he points out WCF 3.5's usernames over transport security cannot be used on IIS-hosted service, although my question was regarding ASP.NET Web Services not WCF.

There's another implementation of HTTP Module called Basic authentication in ASP.NET against custom datasource by Santosh Sahoo.

Although it's not what I wanted, I found QuickStart Tutorial's SOAP Headers sample to be informative workaround. Sending password in plain text over http is clearly insecure, but this example could be extended to add more security, for instance running on https or sending hash of "password + one-time GUID + timestamp".

eed3si9n