Wasted far too long on trying to get WCF to work with custom basic authentication this week. Custom in the sense that I need to look up the username and password in a database and not have IIS attempt to match the credentials to a Windows account. Given how well WCF 4.0 supports RESTful services in general it’s a bit shocking that basic auth over SSL isn’t supported out of the box. It seems like you should be able to derive and hook up a class from UserNamePasswordValidator, set the transport clientCredentialType to Basic and be ready to go. I’ve heard that this works for self-hosted services, but no dice in IIS.
Basic access authentication is a simple protocol and so in the end I added a helper method that checks for access (and in my case returns the user information for later use) at the start of each call into the service. It’s very simple:
- Check WebOperationContext.Current.IncomingRequest.Headers for an ‘Authorization’ header. If it’s there decode and validate the credentials.
- If the header is missing or the credentials are incorrect add the WWW-Authenticate header to the response - WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"myrealm\""); – and then throw a WebFaultException with a 401 Unauthorized status code.
This triggers a browser to prompt for your username and password and then try the request again. When calling the service in code you can add the ‘Authorization’ header preemptively and skip the 401 response entirely.