thefrozencoder

Programming and Technology blog

Rolling Your Own Custom Authentication For ASP.NET


Introduction

ASP.NET Membership combined with Forms authentication provides a convenient way to implement page protection and user authentication.  In some cases this you may want to create your own custom authentication implementation when specific requirements do not allow the built in authentication.  This post shows the basis and a starting point of building your own custom authentication mechanism using ASP.NET.

The code samples in this article can be downloaded using the link at the bottom of this post.  Samples were created using Visual Studio 2008 and using SQL Server 2005 Express.  There are samples for both C# and Visual Basic.NET in the download file as well as a word document version of this post.

Setup

Everything needed to run the samples should be present in the download files.  Before you run the project from VS set the Secure.aspx page as the start up page, when the site is run you should be redirected to the Login.aspx automatically.  From there you can use the login information

  • Login: user@login.net
  • Password: password

There is a setting in the web.config file to control the time in seconds it takes for a user's session to expire I have set this to a low number (5 seconds) for demonstration purposes so once you are logged in and the Secure.aspx page is displayed hit the refresh on your browser a couple of times then wait 5 seconds and do another refresh, you should be redirected to the Login.aspx page since your session has expired.

Requirements

First we will take a look at some common requirements that are typical of a authenticated web site.

  • The system must be able to deny access to all pages that are defined as being secure from anonymous users.
  • The system must be able to authenticate / validate a user before they have access to secure pages
  • Once a user has been authenticated the user will not have to enter credentials again to access secure pages
  • If the user is inactive for x minutes the system will log them out and they will have to login again
  • The logged in session for a user will only be active for the duration of the browser session or until requirement 4 has been met.

Based on our requirements we are going to need a way to store user information; specifically the login and password information.  As well we will need to store some form of a security token that the system creates after authentication and stores a copy of that token in the system as well on the user’s machine.  We store the systems copy of the token in a database and clients’ copy of the token in a cookie (this will cause issues if the client does not allow cookies but for this article that will not be addressed).  We will also need a simple way to implement our security logic for pages that need it.

System Database

Below is the system database tables to store the user information as well as a copy of the security token.

ClientData Table

  • ClientID - will store the unique identifier for the client (used internal to the system)
  • FirstName - will store the users first name
  • LastName - will store the users las name
  • Login - will store the user's login
  • Password - will the users password (tipically the users password is stored encrypted rather than plain text like in this sample)

ClientSessions Table (will store the security token for the user)

  • SessionGuid - will store the system created security token, this value must match the same token on the clients computer (cookie)
  • ClientID (optional) – will store the unique id from the ClientData table for the authenticated user (in some cases this cannot be stored as it may violate privacy laws by uniquely identifying a users session on a site)
  • SessionLastActiveDate – will store a timestamp when the last time the users session was validated
  • SessionTimeOut – will store in seconds how long since the last time the users session was validated before it will expire

User Validation

User validation takes place on the Login.aspx page when the user enters their credentials and the page is submitted.  The system will then query the ClientData table to find a match for the given login and password.  If a match is found the system then creates a security token, saves the token to both the system and the user’s machine via a cookie.  The system then redirects the user to one of the secure pages within the site.  If a match is not found the Login.aspx page displays a message to the user.

Session Validation

Session validation takes place whenever a user browses a page that is considered to be secure.  The page will ask the system if the user has validated by querying the ClientSessions table using the security token from the user’s cookie and match that token to possible existing token stored in the ClientSessions table.  If the session timeout has not expired since the last validation the session is updated with a new last active timestamp.  If the session has expired the user will be forced to the login screen.

Implementation

To implement the logic the following files have been added to an ASP.NET Web Site and shown below is the files that make up the solution

  • The SecurePage Class will implement our authentication logic and be implemented by each of the pages in our site
  • The DataHelper Class implements the data access to the system database
  • The SettingsHelper Class implements the data access to the web.config file for any configurable settings
  • The Sessions.mdf is the database where we will store our user data and the user token
  • The Login.aspx page is interface the user will use to authenticate
  • The Secure.aspx page is a page that the a user must authenticate first to view
  • The UnSecure.aspx page is a page that a user does not have to authenticate to view

SecurePage Class

Below is the implementation of the SecurePage class which all of pages in our site will implement.

  • Line 15 – implements the call made by secure pages to check if the user has been validated by the system to see the current page
  • Line 28 – implements the call made by the Login.aspx page to validate the user against the data in the ClientData table
  • Line 47 – implements an internal call to get the security token from the user’s machine (cookie)

Login.aspx Page UI

The basic login page UI

Login.aspx Page Code Behind

  • Line 8 – The Login page class implements the SecurePage class to implement the methods for our authentication
  • Line 10 - The login button click when the user clicks on the login button the page calls the Login method passing in the values from the login and password text boxes.  If successful the page redirects to a secure page if not displays the user error message

Secure.aspx Code Behind

  • Line 8 – The Secure page class implements the SecurePage class to implement the methods for our authentication
  • Line 10 – The OnPreInit method is overridden so we can call the IsClientValidated method to check if the user has been validated to see the secure page.  If the user has not been validated it redirects to the Login.aspx page otherwise the Secure.aspx page displays as normal

Conclusion

There are other things to consider that are beyond the scope of this article such as using SSL for the login and or secure pages, encrypting persistent data (either cookie or user data), etc.  This by no means is a complete solution but describes the basics in creating custom authentication for an ASP.NET based web site.  This may not be the holy grail of custom authentication but it does offer a few ideas and solutions to implementing your own custom authentication when the built in membership and forms authentication does not fit well with your requirements.  Now you could just have implemented the server storage in a session item and just compared the users cookie value to the session item which would work too but what if your web site is running under a web farm and load balanced?  Unless you use a state server or sql server to store your state you will need a way to persist your authentication in a more permanent or statefull way.

** Note **
The data access layer used is the Microsoft Patterns and Practices Enterprise library which can be downloaded here http://www.codeplex.com/entlib I have encluded only the required assemblies in the download file you may need to download the entire package in order for the samples to run.

Code samples CustomAuthentication.zip (1.49 mb) 

VisualSVN with Active Directory Integration

So I decided to dump Visual Source Safe (VSS) and move to something that is more robust and is pretty easy to setup.  Poking around the internet it became pretty clear that VisualSVN would be my choice mostly because of its integration with Active Directory.  I never liked that fact that in VSS stored it’s user info and settings in a plain text file and anyone who had access to it with modify privileges could change anyone permissions.  This is not really a tutorial but a means to show interested developers and IT professionals just how easy it is to install VisualSVN and integrate it with your Active Directory model.

  1. Pre-Amble
  2. Pre-Setup
  3. Installation
  4. Post-Installation
  5. Active Directory Setup
  6. NTFS Setup
  7. Conclusion

Pre-Amble
The version of VisualSVN I ended up installing is v1.6.2; the server environment is Windows 2003 Standard (32bit).  Active Directory installed and fully configured.

Pre-Setup
If you are like me the first thing you will want to do is create a location for your Repositories.  Since my file server has a data drive (d:) it made sense to create in on that drive so I could do backups from it.  So I created the folder structure [D:SourceControlRepositories].

Installation
When you download the latest msi from the site it informs you that to setup VisualSVN you need to install TortoiseSVN as well.  This is actually not true as TortoiseSVN is just a visual GUI to access the SVN server.  You will need a SVN client like TortoiseSVN add/check in/out files unless you download one of the few VSS provider plug-ins for Visual Studio if development integration is your primary goal.

When you run the installer these are your only options to configure VisualSVN server:

 

Change the Repositories folder to the folder you created in the Pre-Setup section

Change the Authentication to Use Windows authentication

You may want to change the port number if you have some kind of internal numbering scheme for ports but remember VisualSVN uses a fully configured version of apache so you will not need to integrate it with another web server.

When you select the Next button the install will start and eventually complete.

Post-Installation
Once the setup is completed you will be asked to launch the MMC snap-in for configuring the VisualSVN server (note at this time there is no way to configure remote VisualSVN servers if you are looking to install VisuaSVN on a Windows 2008 Core install.  It is however something will be available in the future based on traffic on the VisualSVN Google groups).

Once the MMC launches you can configure the VisualSVN server further as well us it to create new repositories.  You should read the Recommended Repository Layout support topic on best practices on configuring a layout structure when creating Repositories.

When you click on the Server Url in the right hand window you will be taken to the web site of your VisualSVN server.  You will get the common “There is a problem with this website's security certificate.“ error in your browser.  This is due to the SSL certificate that is assigned to the apache web server on install, which is a self-signed certificate.

You will also be challenged with a ACL user name / password prompt.  This information is the same as your domain login since you selected to use Windows authentication.  By default the setup adds the Builtin/Users group from your domain for the ACL list.

Active Directory Setup
To change the ACL groups highlight the Repositories node in the left window -> right click -> properties.  There you will see a common security window you can add or remove groups from your domain.

How I configured my setup was to create a single group in my AD called Software Developers and add users to this group so that only users in this group can access the VisualSVN server.  Depending on your AD requirements you may implement it differently.  One of the nice things about this setup is the fact that the VisualSVN server runs as a service (by default under the LocalSystem account).

NTFS Setup
As I mentioned in the Active Directory Setup section the VisualSVN server runs as a Windows Service under a privileged account.  You will also need to set up your ACL for the SourceCode folder to allow the groups access to read and write permissions.

Conclusion
The entire install was pretty easy and intuitive and with the AD integration it is a breeze to configure and secure.  The only extra thing I did was to create an actual certificate request from the VisualSVN Server Properties window -> Certificates Tab and submit that request to my AD Certificate server.  I then imported the certificate once I authorized it.  What this does is for users that are AD authenticated you will not get the SSL certificate error in your browser or probably any other application that uses SSL to access the server.

As you can see here I have a valid certificate that is authorized within my AD network and thus no more certificate errors

 

Linq to SQL the latest developer drug to be banned?

Recently I have read on various blogs about the demise of one of the newest technologies to enter the .NET framework Linq to SQL.  Well it’s not its demise but from what others have said it’s more like a “don’t count on it being there and updated in the future” statement.  Scott Allen over at OdeToCode has a pretty good blog article about “The Estrangement of LINQ to SQL” and his thoughts on what is going on and how he feels about it.

This is one of the reasons that as a developer of over 10+ years have never really jumped into bed with the latest and greatest technologies/frameworks/methodologies because you never really know if they will be around or supported in a years time.  This is probably why I and a few other developers that I know tend to follow a POD (Plain ol’ Development) process.  While it might not be as glamorous and the talk around the water cooler it surely gets the job done and you more often than not do not get bitten in the ass by the addiction to these gateway drugs.  

Lately it seems that a growing number of developers are showing signs of ADHD (the persistent pattern of impulsiveness part).  Jumping on the latest and greatest just for the sake of “doing it first”.  There are always two sides to the coin, it does drive interesting ideas and development but at the same time I believe that it is creating a whole generation of code that is not maintainable because of how quickly these drugs are dispensed to us and when the next big fix is just around the corner to become addicted to.

 

Note: some of this article was inspired by a fellow developer and friend Shaneo and his post Linq to SQL, MSTest, Unity – Are These Gateway Drugs?

When refactoring goes bad

So I ran into this little nugget this morning while working on a C# WinForms project in VS 2008 (might be an issue in VS 2005 as well).

Compiler Error: The item "*.resources" was specified more than once in the "Resources" parameter.  Duplicate items are not supported by the "Resources" parameter.

Seems that when I copied an existing form and renamed the copy to something else (using the properties window) the refractor tool decided that the source form name needed to be changed as well.  Apparently this is a common issue as I did a search for the problem online.  Normally when you do a rename in a code file you get the option to preview the changes and apply what you want to.  If you do this in the properties window or rename a class file in the solution explorer it seems to just make the change without a preview and globally.

I think that I need more control with this feature so you can turn this off in the IDE under Tools (for VS2008):

  • Options
    • Windows Forms Designer
      • General:
        • Set “EnableRefactoringOnRename” to false.

Doing this still allows you to do your refactoring (via the context menu) but now you have more control over what gets renamed.  And as an added bonus it's also a performace tweek to the IDE.

Been a long time running

Seems like during the summer time I have nothing to say, or rather I don’t usually do much blogging or coding. It is after all summer time.

Except for this weekend or rather today in general. As of lately I have been immersing myself in the world of the ASP.NET MVC bits (preview 4). I never really bothered with the earlier previews since I figured that they would be changing the framework so anything you learned in Preview 1 would probably be obsolete by Preview 5 and I was pretty much right based on some of the samples that I had downloaded.

My main interest is the idea of a pluggable view engine especially a Xml/Xsl transform view engine. A couple of searches via Google and viola I was redirected to the MvcContrib page on Codeplex. After downloading the source and samples I soon realized (probably like others to their amazement) there were no samples for the MvcContrib.XsltViewEngine. There wasn't even a documents page on the site.

So off I went again searching for any kind of help. I ended up finding one post on Google Groups for the MvcContrib that pointed to a blog post (link didn’t work of course). I ended up finding the actual person who created the actual library and the blog post about it and how to get it working (created in Dec '07 - oh boy this was not looking good already). In the end I did manage to get it working after updating the code to work with preview 4 and realized I would probably be writing my own.

And so I did, today actually (rather yesterday now).

More on that later, plus a sample working site with code. But I am tired now.