With the release of ASP.NET Identity 1 and 2.0 and OWIN authentication there has been a lot of changes to the membership system in ASP.NET. But what do you think your chances of seeing one of these authentication systems in production compared to the chances you will see the long lived Forms Authentication? What’s the chances that advancements in one of the newer membership systems will be based off of either components or failures of forms authentication?
Its nearly impossible to work in the sphere of online .NET applications without hearing or coming across an implementation of Forms Authentication. In .Net, forms authentication has been around since at least .Net 1.1 and is still available as of this writing with .Net 4.5. Unfortunately, I come across a lot of developers who have either interfaced with forms authentication because it was already implemented in the project they are working on, or have flipped the few required switches to implement it without really having any idea of the process that occurs when using forms authentication or given any thought to security implications.
Therefore, this post sets out to lift some of the fog and takes a closer look at the process that authentication undergoes when using forms authentication with an eye on security implications.What this post does not do is walk you through implementing it. There are a ton (and that is not an understatement) of tutorial’s out there that will do that for you.
Forms Authentication Revealed
At the highest view, forms authentication is a ticket based authentication mechanism. This mechanism can be easily viewed as providing a user of the system an admission ticket that they will need to provide on any subsequent requests for admission. I like to equate forms authentication to a amusement park ticketing system. In order to have access to the park’s amenities, you first visit the ticket booth to purchase an admission ticket. Then you proceed to the park’s admission gates where they are going to require you to have a ticket that they recognize and accept.
Forms Authentication is not in itself or contain in itself the mechanism used for authentication (its not the mechanism the park’s gate attendant uses to validate the ticket). It however provides the framework for identity or role-based access control in your application. In relation to our park admissions example, it can be viewed as a framework setup to provide a ticket that a valid customer who upon submitting the ticket at anytime, the framework can validate the authenticity of the ticket itself, validate the customer’s admission and authorization to area’s of the park and finally make that ticket easily available to other internal area’s of the park.
One of the first switch that we flip to enable forms authentication is enabling a HTTP Module FormsAuthenticationModule in the web.config:
Fig 1
<authentication mode="Forms"> <forms loginUrl="Login"/> </authentication>
HTTP Modules: A Quick Detour
Before jumping head first into the Forms Authentication workflow, lets take a quick detour around the implications of an HTTP Module in the ASP.NET framework and what that means to us. There are a number of extension points to the different ASP.NET applications (MVC, Web Forms, Web API, etc..). Each extension point providing a hook into a particular place in the application’s pipeline. Just as driving to a destination in your car, each street might get you closer to your targeted destination, so each extension point in the application’s pipeline runs closer to intended target.
To illustrate this point, lets take the example of a GET request to the resource http://myserver.com/Account/Profile in a ASP.NET MVC application. In this case, the intended target is the Profile method on the Account controller. As the HTTP request comes in through the entrance point of the pipeline, it travels through the pipeline with the intended goal of being serviced by the Profile method. Each different extension point in the pipeline is executed closer to the targeted code in the Profile method.
HTTP Modules are one of the earlier executed extension points in the pipeline. The key here is that the FormsAuthenticationModule is an HTTP module and therefore runs fairly early in the pipeline allowing you to handle malicious request before it is exposed to a considerable amount of application code. On the flip side, it also is no longer host agnostic as HTTP modules are specific to IIS. There are a number of other trade-offs with using HTTP Modules, some for better some for worst. I am not here to convince you whether HTTP Modules are best suited for your situation, but understanding where processes occur in the pipeline is strategic when it comes to security in your application.
[alert type=”info”]In some cases, the importance of where you are handling specific security related issues can be as important as whether you are at all.[/alert]
Stepping Through The Process
And We’re off with IIS
With IIS hosting the ASP.NET application due to the requirements of HTTP Modules, it will receive and initially handle all requests. Its first point of business when receiving a request is to apply an authentication scheme which is separate from the authentication we have talked about up to now. There are a number of different authentication schemes in IIS, but by default IIS is configured with the Anonymous Authentication scheme. In the case of Anonymous authentication, IIS is not actually performing authentication of the client directly as the client has not been required to provide any credentials. Rather, IIS is going through the process of establishing the client as an anonymous user. IIS then creates a token representing an anonymous user and passes this onto ASP.NET with the request.
ASP.NET Joins In The Fun
At this point, there has been no restriction to the application, all clients are being sent to the ASP.NET framework as an anonymous user. Therefore, in order to take the next steps through Forms Authentication we need to impose the process of authorization on all requests for all clients. This can be done with the authorization and deny attribute in the web.config:
Fig 2.
<authorization> <deny users="?"/> </authorization>
So running with the example we were using before with a client attempting to access the restricted resource http://myserver.com/Account/Profile we can now see Forms Authentication take affect in the application as ASP.NET as it will first attempt authentication based on the mode defined in the authentication attribute of the web.config (see Fig 1).
Another module, UrlAuthorizationModule will then determine whether the current user has authorization for the requested resource. Based on the deny attribute, UrlAuthorizationModule determines that all anonymous users have been denied access which is denoted by “?” in users=”?” (see fig. 2). Therefore, it sends back a HTTP status code of 401 – unauthorized.
However, instead of this being received by the client, it is intercepted by the FormsAuthenticationModule and redirects the client to the resource specified by the LoginUrl attribute of the web.config (see Fig 1) which in our case is the Login resource. You can see where we are in the process below.
Short Commercial Break
Now, I want to take quick detour and point out another security implication. I haven’t mentioned anything about HTTPS, SSL/TLS when talking about login forms for the sake of focus. But I do want to bring attention to a security issue that can easily be exploited when talking about login forms. Many times we will come across login pages that are not operating under secure HTTP (HTTPS), with the notion that the posted credentials are being posted to a secured resource (i.e. POST https://myserver.com/Account/Login).
Unfortunately, this opens the door for a MITMA (man-in-the-middle-attack) to occur to that page that could compromise the security of the users credentials prior to it being securely posted to the login recourse. To drive this home. It isn’t much to ask for embedded scripts to get added to compromised pages that might key-log every key entered on the Login page.
So the next time you are on the login page of that http://www.myfavoriteshop.com site and don’t see that the site has been served up via HTTPS, might give you pause. But if anything, this might give you food for thought the next time you are implementing that next login page.
Continuing On
ASP.NET application has returned the Login view to the client which can now be used to post back their credentials. The user for the request to the post Login resource still comes in as an anonymous user. From the post Login resource, the application would conduct the necessary authentication measures it has in place to authenticate the user in the system.
ASP.NET applications such as web forms and MVC, just to name two, have been providing additional authentication mechanisms such as membership providers for identity and role-based access controls in various templates (i.e. internet template). These authentications can provide the authentication and authorization that your application require or you can provide your own custom mechanisms. We are not talking about these authentication sub systems.
Upon a successful authentication, Forms Authentication will generate a ticket (like the one in the opening example) and transport it in a cookie back in the response to the client.
For the sake of simplicity, the cookie is more or less a container for the important data, the ticket. The cookie will be provided to the application for every subsequent request by the client/browser. The information in the ticket is the relevant and sensitive information that the system will need to validate the user’s authentication and verify authorization. Therefore, this information is encrypted using a 256 bit symmetric key encryption, AES algorithm (which is the Rijndeal Algorithm for those that care). AES is the default encryption , but this can be configured in the web.config (see this documentation for more information).
Now that the user has been authenticated and provided a ticket, they will be redirected to their original request. We are making an assumption that we are keeping track of their original resource request /Account/Profile. The difference this time is that the request will have the cookie which contains the Forms Authentication token. Decrypted, the Forms Authentication can validate the user has been authenticated and creates the GenericPrinciple object and assigns that to the HttpContext.
For another quick detour, a Principle object contains an Identity object. The Identity object represents the user. While the Principle object represents the security context of the user which includes the identity and roles they have been assigned (in the case of role-based access control).
The UrlAuthorizationModule performs its duties to verify the user has the authorization to the requested /Account/Profile resource and returns the associated view with a status code of 200.
Putting It All Together
In conclusion, we can see there are quite a few pieces that fit together to facility a system for tracking a users authentication and authorization. There have been a number of changes to Forms Authentication over its life time, but in the end most of the core components have remained. There are some shortcomings as well as some dependencies such as with the required use of IIS. However, it has grown popular over the years to the point that an everyday .NET developer of online systems would be hard pressed not to encounter forms authentication at some point in their career. Finally, we also covered a few security points regarding keeping a mind of where authentication and authorization occurs in relation to where your code executes and thoroughly examining what responses should be served over SSL/TLS.
Obviously, there are a ton of facets about Forms Authentication that we didn’t cover such as the specifics of identity and/or role-based access control and configuration options just to name a couple. However, the intent of this post was to lift the fog of Forms Authentication for the everyday developer by walking through the workflow that occurs when using this ticket based authentication mechanism.