In this article we will do a deep technical dive into ASP.NET Identity and the role that it serves in providing basic Identity management (IdM) for enterprise applications using ASP.NET MVC. ASP.NET Identity is the default identity management API that is installed with Visual Studio 2013 and ASP.NET MVC 5. Although ASP.NET Identity would probably not be used in production intranet environments, the goal of this article is to provide an understanding of baseline IdM requirements for enterprise applications.
The illustration below summarizes the relationship among an application, it's users, and it's modules in it's most simplest earliest form. Early web-based applications consisted of users and modules. At this point, every one of the users have access to all modules in the application.
I am assuming that you have a basic understanding of using Visual Studio and SQL Server to create ASP.NET web-based applications. We will be referring to some of the ASP.NET code to help illustrate IdM concepts. However much of what we cover in this article and subsequent articles is considered to be in the area of DevOps – the integration between software development and IT particularly the operation and infrastructure aspects of IdM.
I recommend having the ASP.NET source code in front of you for reference. You can do this one of two ways:
In subsequent articles I will integrate our sample enterprise application with external IdM services more likely to be used in production environments:
Now we will list the requirements for identity management in our line of business application. The application will be used by company employees particularly financial advisers.
Users must log into the application to access any of its functionality except for of course the log-in page itself.
User accounts must be created by another user with administrative privileges.
There will be 4 roles: Admin, Demographics Editor, Financial Manager, Online Access Manager.
All roles can at least view account holder data.
Users in the Demographics Editor role can modify account holder’s demographic (address, phone, email address) data.
Users in the Financial Manager role can modify account information
Users in the Online Access Manager role can modify the account holder’s online access.
All application roles are predefined. There is no administrative creation of roles.
Each user may be a member of zero or more roles.
There will be a self-service function that allows the user to change his/her password for the system.
The sample demo ASP.NET MVC application that will be used in this article is a management application used by financial account managers for the fictitious company Footloose Financial Services for managing their clients. It was created using the default ASP.NET MVC template with a customized user interface from the marketing folks at Footloose. Below are some of the features of the application.
Identification – Create (Register) a new user
The system allows a new user to be created or registered so that the user can have access to use the system. Typically this function would be performed by a user with administrative privileges however in the default ASP.NET MVC template this function is not limited to administrative users (we will discuss how to limit this feature to administrative users later in the next article).
Authentication – Log into the system
Once the user has been registered she can log into the system using the login screen. All screens and web services in the system require authentication. If the user passes authentication, she is taken to a web page that she has originally requested before authentication.
Subsequent page requests do not require entering credentials again because a authentication browser cookie is stored in the user’s web browser that is used by ASP.NET Identity to identify from whom the request came. The cookie remains active in the user’s browser until it expires at which point the user will need to log-in again to continue using the application.
Self Service – Manage your account
The system will allow the user to change her password.
Once the user is logged into the system, she can manage her clients.
As an application that is internal to the company and not public facing, authentication through individual user accounts is not ideal and it would be more efficient to use an external service such as Active Directory that can be managed by a separate security department. However for the purpose of understanding the individual technical components of IdM it’s a good idea to have an understanding of what Microsoft offers for individual user accounts.
Setup and Configure the Visual Studio project
If you download the source code for the same project you will need to perform some actions in order to get it up and running.
1. Download and install SQL Server 2012 Express
The Footloose Financial application uses SQL Server as the database engine. You can either use an existing SQL Server 2012 instance or download and install SQL Server 2012 Express for free.
2. Attach the FoolooseFS.mdf file to your SQL Server instance
The github commit labeled "Added FootlooseFS MDF file for SQL server" has a copy of the SQL Server data (MDF) file for the application in the App_Data folder. Create a new database in your SQL Server instance called "FootlooseFS" and attach the MDF file to this database so that you have the database schema and sample data of account holder. In the web.config file there is a database connection string called "FootlooseFSContext" that has the database connection parameters that the application expects. The MDF already has the database user "FootlooseFSdbuser" and sample data however you will need to change the data source to match the name of your SQL Server instance.
3. Create an ASP.NET Identity user called "admin".
After you build and run the application, you will also want to register an application user called "admin" with a password of your choosing. You will need to login as an application user to access any of the functionality in the application. Also we will need an "admin" user for the next article regarding roles.
ASP.NET Identity is the identity and authentication management system built into ASP.NET. It provides the following IdM services for enterprise web applications to manage it’s user base:
Add to, update, and delete users from the system
Add to, update, and delete roles from the system
Add users or remove users from a role.
Log in and log out users from the system.
Extend the properties of a user
Link their system account to an external service such as Facebook or Twitter
Identification is the process of creating accounts in a system that represent a physical users or processes who will be using the system. ASP.NET Identity supports identification through a database interface and functionality for managing users through its API.
Authentication is the process of a user validating who she says that she is to get access to a system. ASP.NET Identity supports authentication by providing an additional API for validating a user against her password. ASP.NET Identity provides several other features that will not be covered in this article including external access to social media accounts, claims interface, and OWIN Integration.
The following article from Microsoft provides more information about ASP.NET Identity: http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity
ASP.NET Identity configuration and API
Let’s take a look at how ASP.NET Identity is configured and utilized in the sample solution.
Database connection to ASP.NET Identity data store
The FootlooseFS.Web.AdminUI project was developed using the MVC 5 template so we’ll start with the web.config file. The “DefaultConnection” database connection string is the connection string for the ASP.NET Identity database of users and roles. By default the ASP.NET Identity database is a SQL Server LocalDb instance that is embedded into the application.
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApplication1-20140224105332.mdf;Initial Catalog=aspnet-WebApplication1-20140224105332;Integrated Security=True"
This can be modified by the developer to point to an ASP.NET Identity database on a separate SQL Server instance however the database schema must remain intact. Now let’s look at the database schema. From the VS solution, click on the Server Explorer tab and open the “Data Connections” and “DefaultConnection” and “Tables”. These tables store the data that ASP.NET Identity uses to perform it’s tasks. The AspNetUsers table stores the users who have access to the system.
ASP.NET Identity API
Now let’s look at how the ASP.NET Identity API is used to create users and permit them to log into the system. Go back to the Solution Explorer tab and within the FootlooseFS.Web.AdminUI project, open the Controllers folder and view the AccountController.cs file. This is the code file that uses the ASP.NET Identity API to implement identification, authentication, and self-service. The UserManager class exposes user related API for creating and updating users in the ASP.NET Identity data store. Below are several of the key methods that the application uses.
FindAsync – Find a user in the data store that matches the given user name and password.
CreateAsync – Create a user in the datastore with the given user information and password.
ChangePasswordAsync – Changes the password of the user in the datastore specified by given user ID.
CreateIdentity – Create a claim from the user and the authentication type for logging into the system.
The other class in the API that we are concerned about is the AuthenticationManager class. This class manages the authentication modules during the client authentication process. Below are the key methods that the application uses.
SignIn – Signs the given user into the system and persists the authentication given a given mechanism which is typically a browser cookie. That way if I want to go to another web page in the system I do not need to enter my credentials again because the authentication browser cookie is proof that I have already been authenticated.
SignOut – Signs the user out the system and terminates the persisted authentication typically by deleting the authentication browser cookie. Because the cookie has been removed, the next time I access any web page in the system I need to login again.
The UserManager and AuthenticationManager classes provide the functionality of creating the user and logging the user into the system. This functionality is provided by default without any additional coding when a website uses MVC 5 individual user account authentication as the template. However it is important to understand what these classes do in case you want to change the default functionality (for instance in the next article we will cover roles and we will move the user registration feature to a separate page for users in the admin role).
ASP.NET MVC and IdM
Lets look at some other out-of-the-box functionality that ASP.NET MVC provides to make IdM work in enterprise web-based applications.
I want to configure all web services to require authentication.
ASP.NET MVC provides the concept of a filter which is essentially a rule that is applied to all web services (which is called controllers in the MVC world). In the file App_Start/FilterConfig.cs, global filters are registered, which means they will be applied to all controllers. The AuthorizeAttribute indicates that all web service functionality including all web pages require authentication.
public class FilterConfig
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
If all web pages in the system require authentication to access them, how am I able to access the login page?
Good question. If you look closely at the AccountsController.cs file you will notice that most of the methods have the [AllowAnonmous] attribute above them. This tells MVC that these controllers do not require authentication. This allows unauthenticated or anonymous users to access these bits of functionality.
Where do I specify the exact login page and authentication persistence mechanism to be used?
In App_Start/Startup.Auth.css, the login page (or path) and authentication persistence method is specified. By default in the MVC 5 template, the login page is /Account/Login and the persistence method is the browser cookie. These settings can be customized to use a different web page for authentication or an external cookie, such as a Facebook cookie for authentication persistence.
I want the authentication cookie created by ASP.NET Identity to expire after 8 hours.
By default the ASP.NET authentication cookie does not expire (at least not in a reasonable amount of time). Typically we would not want this cookie to last for longer than a day if we never manually click the Logout link (and who ever bothers to click the Logout link when they are done with the application?). So let’s change the expiration of the cookie to 8 hours. In the StartupAuth.cs file, we can change the ExpireTimeSpan property of the of the CookieAuthenticationOptions class so that the cookie expires after 8 hours.
LoginPath = new PathString("/Account/Login"),
ExpireTimeSpan = new System.TimeSpan(8, 0, 0)
After you log into the system you will be prompted to log in again after 8 hours regardless of activity or inactivity. If you want the cookie to expire after 8 hours of inactivity or idle time then you need to indicate to ASP.NET Identity that you want a sliding expiration. This means that the cookie will remain active as long as it is accessed by ASP.NET Identity. Set the SlidingExpiration property to true.
LoginPath = new PathString("/Account/Login"),
ExpireTimeSpan = new System.TimeSpan(8, 0, 0),
SlidingExpiration = true
Take a look at the following article for a deeper understanding of how the ASP.NET form authentication cookie works. It covers the information stored in the authentication cookie, the encryption method used to store the information, and how you can setup default properties on the server in the machine.config file. Understanding the Forms Authentication Ticket and Cookie
I want to move the user registration feature to an admin page that can only be accessed by admin users.
It’s a good idea to separate admin features in the application (such as creating user accounts in the system) from the standard business functions. However before we do that we need to establish a process for creating roles and assigning users to a role. We will cover that in the next article.
I am a senior software engineer and technical lead for a mid-sized technology firm. I have an extensive background in designing, developing, and supporting ASP.NET web-based solutions. I am currently extending my skill-set to the area of application identity management and access control.