Using my WCF http Basic Authentication code in VS 2012

I blogged about the implementation of http basic authentication that I made in this post here, but this is a more detailed description of how to get it working in a simple WCF service in Visual Studio 2012.

First, you'll need to set up a basic out-of-the-box WCF service in Visual Studio 2012:

...and change it slightly so that it can be used from a browser, as described in this post here. You should now be able to call your service from any web browser to see it's working properly.

Personally, I just stuck to the default Microsoft code example and added a [WebGet] attribute, like this:

[WebGet(UriTemplate="getdata?num={value}")]
public string GetData(int value)
{
   return string.Format("You entered: {0}", value);
}

...which means that I can call http://localhost:8080/Service1.svc/getdata?num=1 to pass a querystring value to my method.

Now, add these files to your project (BasicAuthenticationAttribute.cs, BasicAuthenticationHttpHeaderInjector.cs and BasicAuthenticationPasswordValidator.cs). When you've done that, just add the [BasicAuthentication] attribute to your service class. That's it! Try running the project again.

You should be asked for a username and password by the browser. Now, the WCF service will only return some data when you have used these details: username='user' and password='password'. You can change the BasicAuthenticationPasswordValidator class to implement whatever means you like to check that the user is authorised.

You now have a code-only implementation of http basic authentication for WCF. If you're using IIS, you don't need to configure anything to make this work, as far as IIS is concerned you are using anonymous access. But it should also work in IIS Express or the Visual Studio Development Server.

NOTE: this code makes no attempt to encrypt the username and password you type into the browser. The details will be sent in clear text as an http header. You should at least consider using https to encrypt the data. The purpose of this code is just to show how http basic authentication works, and how it could be done in code.

WCF HTTP Basic Authentication in Code

So I wanted to build a WCF service with a very simple authentication mechanism, and I thought that it would be good to start with my own implementation of http basic authentication - and then I could go from there, adding my own extras to the protocol if I wanted. But I thought that basic authentication over https would at least be a start.

And even though the username and password are sent in clear text, doing that over an https connection should be safe since it's encrypted before going over the wire.

Finally, I wanted to do the whole lot in code, so that I can deploy it to some hosted space without fiddling around in IIS. But also because I like code :-)

The good thing is that basic authentication is supported by most browsers, so I could expose the WCF service as web methods and test it very easily. I have assumed that since it works with all the major browsers I have implemented the protocol correctly.

The end result was a custom attribute which can be added to a WCF service and does all the work for you. The only other thing that needs to be done is modify the method which decides if a user is valid or not.

Here is the source code (click the image to download):

I'll post an example of how to use it (in Visual Studio 2012) in another blog.

More fiddling with MVC3 and https

I blogged here about securing logon cookies in MVC3. After writing a custom attribute based on the [RequireHttps] attribute it turned out that the best way was to use the forms authentication properties in web.config instead.

But the custom attribute that I wrote ended up morphing into something that solves a different problem. When you use the [RequireHttps] attribute, you might notice that even when a user logs out they continue with an https connection on subsequent requests to your site. This is not a big problem, but I find it annoying since https is not needed anymore. A similar thing might happen if a user has accidentally bookmarked the https version of your site's homepage, in which case the encryption might be unnecessary.

So I changed my existing attribute class into the [LimitHttps] Attribute. It checks to see if you are using a secure connection AND are not authenticated, then switches you back to plain old http - unless you are visiting a route that requires https. This is how I'm using it:

1) add the [RequireHttps] attribute to Account\LogOn and Account\Register
2) set up forms authentication with requireSSL="true" in web.config
3) add this line to RegisterGlobalFilters() in Global.asax:
     filters.Add(new LimitHttpsAttribute());

You'll now find that the following things happen:

- https will be enforced when a user is logged in
  (this is due to the requireSSL property in web.config)

- if a user manually goes back to http, the login cookie will not be sent in the request
  (also due to the requireSSL property)

- The LogOn and Register views in the Account controller will always use SSL (https)
  (because we've added the [RequireHttps] attribute to them)

- when a user logs out, they will automatically revert back to http
  (which is done by the [LimitHttps] attribute we've added)

- if a user visits the homepage with https they will switch back to http
  (the [LimitHttps] attribute does this too)

The code can be downloaded by clicking below.
Download the [LimitHttps] attribute