Implementing Smart Card Authentication with ASP.NET - Introduction

8:24 PM j. montgomery 10 Comments

Page 1 of 9

Next Page: Building and Installing the Smart Card HttpModule

In my previous article last October on Smart Card Authentication with ASP.NET, I introduced the topic of using Smart Cards to handle Authentication and Authorization with ASP.NET for non-Active Directory users. This is a more complete follow-up article now that I have done a bit more research into the topic and now have a full working implementation that I’m happy with.

In this implementation, the IIS Web Server is handling the basics of the Smart Card authentication, much like Windows authentication works.

The goals of this project are to provide the following:

  1. A tight interface to strongly typed objects that are Smart Card aware
  2. Allow these typed objects to be available to the entire web application on every page request
  3. Provide Role based authorization via the smart card through groups. This will require a mechanism to associate a User’s smart card with an associated group

Some Caveats

If you do not need to apply role authorization through Principals then this methodology may be more then you need. If specific requirements stipulate you need information on the Smart Card/Client Certificate to display on the screen or track the Certificate Subject, simply using IIS for Authentication and the HttpCertificate property of the Context object (Context.Request.ClientCertificate) will be sufficient.

If you plan on doing Client Certificate Mapping to User Accounts on the OS or Domain, this methodology is not necessary. If the reason is not immediately obvious to you, the short answer is that when using Certificate to AD Account mapping, IIS is taking the smart card and mapping it to a Windows Account – so in the end, IIS is using Windows Authentication. Once you have mapped an account from a smart card to a windows account, you can use Windows Authentication in the Web.Config and the WindowsPrincipal object for Authorization based on Windows Groups.

Background

In my original implementation of Smart Card authentication and authorization with ASP.NET, I used Forms Authentication in combination with the Request.ClientCertificate to automatically authentication the user. Instead of having the user enter their credentials on the Forms Login Page, this methodology still redirected them to the forms login page, but instead of the user needing to type in their username and password, the code behind automatically resolved the Request.ClientCertificate and authenticated them against the database. Next the code created the FormsAuthenticationTicket (which included the roles) as a cookie, and then redirected them back to the original page they were requesting. Finally, the Principal was attached to the Context.User object in Application_AuthenticateRequest event of the Global.asaxFor implementation details, see: How To: Create GenericPrincipal Objects with Forms Authentication and How To: Use Forms Authentication with SQL Server 2000 – I combined and modified these two methodologies for use with the Smart Card.

After having used Forms Authentication in the original version, here are some lessons learned I will share. The Forms Authentication approach ended up not being a very good approach for several reasons:

  1. Forms Authentication relies on page redirects to handle authentication via a Login page. This adds unnecessary overhead since there is no reason for the browser to jump around via redirects to retrieve the Request.ClientCertificate. The certificate is immediately available once the user is authenticated via IIS.
  2. Forms Authentication relies on encrypted cookies to store the users’ authentication data in the FormsAuthenticationTicket.UserData property (which was the users’ roles are typically stored). Since we already have the Request.ClientCertificate, using cookies for authentication adds additional complexity to the code.
  3. Encrypting and decrypting the FormsAuthenticationTicket adds extra processing overhead.
  4. It does not make sense to push data down to the client in a cookie since we’ve received all authentication information we need already. From a threats/countermeasures perspective, since the cookie comes from the client, we must treat it suspiciously and perform extra validation on the User Data to make sure it was not tampered with. Yes, even though its 3DES encrypted MAC is enabled –the threat must be considered where one is able to crack the 3DES key, however unlikely, and decrypt the FormsAuthenticationTicket. If we put nothing on the client, this threat will never be realized.
  5. Forms Authentication adds unnecessary authentication complexity to the code in Global.asax as well as code in the Forms Login page.
  6. The Forms authentication mechanism caches the login for duration and has ‘logout’ functionality via cookie expiration. Smart Cards in ASP.NET do not ever ‘log out’, they timeout. Since IIS handles the re-authentication transparently to ASP.NET, the .NET authentication code need not handle timeout and re-authentication.

A more appropriate way of handling the Smart Card authentication and authorization is using a feature of ASP.NET called HTTP Modules.

HTTP Pipelines

ASP.NET has built in a nice way to insert code into the HTTP Pipeline. This is an ideal place to insert code to handle new types of Authentication (as well as many other things). This will not be any shock to those already familiar with the ASP.NET HTTP pipeline – the other authentication models in ASP.NET (Forms, Windows, and Passport) are implemented in the HTTP pipeline using HTTP Modules. Session management and URL Authorization are also handled with HTTP Modules. If you are not familiar with HTTP Modules and the HTTP Pipeline in ASP.NET see Appendix A for more reading on the topic.

The concept behind the HTTP Pipeline is simple. A web request comes in from IIS. If the page is mapped to run through the ASP.NET engine, IIS passes the request off to ASP.NET and then ASP.NET moves the request through all the HTTP Modules installed in the machine.config as well as the web.config. Here is a picture demonstrating the pipeline:

Figure 1 – HTTP Pipeline in ASP.NET
Figure 1 – HTTP Pipeline in ASP.NET

To resolve programmatically the HTTP Modules loaded currently in ASP.NET, drop the following code in the _Load event of any ASP.NET page:

C#

1 private void Page_Load(object sender, System.EventArgs e)
2 {
3 Response.Write("<b>Loaded HTTP Modules</b>");
4 Response.Write("<br>");
5
6 foreach (string httpModule in this.Context.ApplicationInstance.Modules)
7 {
8 Response.Write(httpModule);
9 Response.Write("<br>");
10 }
11 }
12

VB.Net

1 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
2 Handles MyBase.Load
3
4 Response.Write ("<b>Loaded HTTP Modules</b>")
5 Response.Write ("<br>")
6
7 For Each httpModule As String In Me.Context.ApplicationInstance.Modules
8 Response.Write(httpModule)
9 Response.Write("<br>")
10 Next
11 End Sub
12

The output will look something like this:


Figure 2 – ASPX page lists the currently running ASP.NET modules.


Figure 2 – ASPX page lists the currently running ASP.NET modules.


Notice that all of the HTTP Modules that come with ASP.NET are loaded even when a particular feature is not being used (i.e. Session Management, Forms Authentication). While loaded, they do not do any work on the Request unless the web.config file is used to enable it.


Here is an outline of the steps the rest of this article will cover:


  1. How to Build a Smart Card HTTP Module
  2. Configure an ASP.NET application to use the Smart Card HttpModule in the web.config file.
  3. Configure IIS to support Smart Cards
  4. Create the Smart Card Principal and Smart Card Identity objects and add the logic

Next Page: Building and Installing the Smart Card HttpModule


Page 1 of 9

10 comments:

  1. Hey, j. montgomery!
    Very thorough work!

    You may look into simpler solution where the client certs are verified by IIS, then certs are mapped to windows accounts - no need for AD, and then role based authorization is applied either via URL authorization or principalpermission attribute

    Here is how it can be done for web services:


    http://blogs.microsoft.co.il/blogs/alikl/archive/2007/01/29/SOA_2C00_-Strong-Authentication_2C00_-Standard-Authorization-_2D00_-Cool-Solution.aspx

    ReplyDelete
  2. I considered that, but I have some problems with that scenario:

    1. A lot of our users who need to use this system are NOT in active directory.

    2. Management overhead. Adding 1-to-1 mapping of several thousand users is a logistical nightmare.

    3. Last, but not least, you have to know each users password setup their certificate to AD mapping. This deminishes security as someone needs to know all the users passwords other then Active Directory.

    For a smaller implementation, what you suggest is very reasonable, but for a large enterprise it doesn't scale well.

    ReplyDelete
  3. Hi J,

    Thanks for your article. Our company wants to implement 2 factor authentication.We decided to use USA token instead of smartcard for the reason of not tampering with user computers. We use ASP.NET 2.0 with C#. Do you have any info on how to implement RSA SecureID token authentication with ASP.net. Do we need forms authentication along with this. Currently, we are planning to.

    I appreciate your response.

    Thanks,
    Katta

    ReplyDelete
  4. > Do you have any info on how to
    > implement RSA SecureID token
    > authentication with ASP.net.

    I'm very curious about this as well - let me do some research and get back to you!

    ReplyDelete
  5. In our scenario, we will have smartcard certs mapped to windows accounts in AD. Is there anyway to tell that they user used a smartcard and not their username/password to authenticate on the local machine?

    Thanks to HSPD12, we have been mandated that we will only use smartcards.

    ReplyDelete
  6. Hi,
    We have a web application [VS 2003] using windows authentication. We need to implement smartcard authentication for that application. I was wondering if we can acheive this just by IIS configuration changes instead of any code change in the app. Can you please help us in this?

    ReplyDelete
  7. > I was wondering if we can
    > acheive this just by IIS
    > configuration changes
    > instead of any code change
    > in the app

    Depending on your requirements, you can get away with no code changes! If all you just need to do is verify that a smart card is signed by a specific Certificate Root Authority (CA) for authentication only, then you can configure that in IIS and shouldn't need to make any application changes.

    If you need to do authorization/role validation then you will have to make some code changes or setup Smart Card to map to Window accounts and use windows Groups to limit access....

    ReplyDelete
  8. While I am intrigued by the usefulness of something like this I am bother by many different things. First your C# code is wrong. Instead of Me it should be this. Also I make the changes to my web config file as instructed and the page won't compile. Another annoyance is where is the source code that I can download?

    ReplyDelete
  9. yep, you are correct - it's a mistake, - you can download the sample code linked from this post here:
    http://securitythroughabsurdity.com/2007/05/sample-code-authentication-and.html

    ReplyDelete
  10. Hi

    Is it spossible to somehow use this solution and to have ASP.NET web application that will use ADFS 2.0 as STS and automatically authenticate users that have inserted their Smart Cards. ADFS will authenticate users agains AD.

    ReplyDelete