SSL Client Side Certificate Authentication Web API 2

Several enterprises prefer to work either on intranet or in a closed circuit over the internet. These enterprises prefer their applications to be secured based on information which only they can produce and can not be hacked easily. One of these ways is the client side certificates. Certificates are issued to the individual users and can be used later to identify/authenticate the users. Lets start with the implementation.

Create a Empty Project with Web API 2

Create a new project in visual studio (mine is 2013) following the steps given below

  1. Create an Empty Asp.net web API project.
  2. from nuget package manager or console, install Web API 2 to make sure the latest version is updated. You will have the following directory structure for your project.

ssl_client_cert_1

Add a Controller

  1. Add an Empty Web API 2 controller and name the controller as AccountController.
  2. Add a simple method to the controller with the following code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace WebApi2.Controllers
{
    public class AccountController : ApiController
    {
        [HttpGet]
        public string authenticate() {
            return "authenticated";
        }
    }
}

Lets try to call this service with https binding.

Enable SSL on Server

For local testing in visual studio IIS Express, enabling SSL is easy with the following steps.

  1. Open the solution explorer and select the Web API project.
  2. Open the properties for the project by pressing F4. (Note: Clicking the project and opening the properties is different then right clicking the project and selecting the properties at the end of the menu)
  3. ssl_client_cert
  4. The properties window gives a developer options to set limited environmental configurations for IIS Express.
  5. ssl_client_cert_2
  6. From here we can turn the SSL Enabled to True.
  7. As soon as we enable the SSL a new URL will appear against SSL URL.
  8. ssl_client_cert_3
  9. IIS Express has a new https binding to test our API on the port 44304.
  10. A request to https://localhost:44304/api/account/authenticate with http verb GET returns a string “authenticated”.

To enable SSL on IIS 8 or above there is a detailed tutorial on certificate installation in IIS 8. A brief summary is as follows

  1. Install a certificate on the server by selecting the server from the left menu and from the center select Server Certificates > Complete Certificate Request…
  2. Certificates can also be installed by double click the .pfx file.
  3. If single website is to be hosted, certificate can be stored in the personal store. For multiple sites hosting using SNI, certificates can be stored in web hosting store.
  4. Add https binding for the website. While adding https binding, the SSL certificate is to be selected.

SSL Client Certificates

At this point we want the IIS to enforce the browsers to present some certificate before moving forward. It can be achieved with the following setting in applicationhost.config.

<access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
<iisClientCertificateMappingAuthentication enabled="true">
</iisClientCertificateMappingAuthentication>

To enable SSL negotiation in IIS Express for testing, a great write up is available at Client Certificates in IIS Express.  However summary of the post is as follows

  1. A client side certificate is needed either installed on the machine or a smart card. A quick way to create a dummy self signed certificate is http://www.selfsignedcertificate.com/.
  2. Locate the applicationhost.config file and make the necessary changes as mentioned above. For visual studio 2015 the file is avaiable in the [solution directory]\.vs\config\. If not working with a solution directory, .vs folder should be available at the parent directory. For visual studios older then 2015 the applicationhost.config C:\Users\[username]\Documents\IISExpress\config\.
  3. Restart the IIS Express server so that the changes are loaded.

To configure client certificate negotiation on IIS 8.0 or later follow the steps below summarized from the post

  1. In IIS select the site you want to manage. SSL settings are not available for the server level. You can also select a file in the content view. Once a file is selected, click switch to features view in the action pane.
  2. Select SSL settings from the middle menu and select Require SSL.
  3. On SSL Settings page, In the client certificates area we have three options
    1. Ignore: Ignores the client certificate even if it is provided
    2. Accept: Accepts a client certificate but do not enforce it.
    3. Require: Makes it mandatory to provide a client certificate, if not provided the request is not entertained. To use Require option, Require SSL should be selected for SSL settings.
  4. Click apply from the action pane.

Accept SSL Certificate in API Controller


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Security.Cryptography.X509Certificates;

namespace WebApi2.Controllers
{
    public class AccountController : ApiController
    {
        [HttpGet]
        public string authenticate() {
            X509Certificate2 cs = Request.GetClientCertificate();
            var subject = cs.Subject;
            return "authenticated";
        }
    }
}

Request.GetClientCertificate() returns a certificate if the request contains a certificate and null otherwise. Once we have the certificate we can parse and implement further authentication rules according to our requirements.

Conclusion

Client certificates are very sophisticated way of providing security following the PKI principles. Accepting a certificate from the client is not enough as they are mostly public certificates they must be signed with a private key which should be trusted with the server.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s