Introduction to ASP.NET Core Identity

In this Introduction to ASP.NET Core Identity, let us learn how to use Identity API to add login functionality to a web application. We will learn what is ASP.NET Core Identity is Its Architecture & How to Create an ASP.NET Core Project with identity Enabled. Next, we will dive deep into the Identity Code, Scaffold Identity UI, and examine the register, login & logout functionalities.

What is ASP.NET Core Identity

ASP.NET Core Identity is a fully-featured membership system for creating and maintaining user logins. Using Identity API, you can sign in & sign out users, reset their passwords, lockout users & Implement Multi-Factor Authentication. It can also integrate with external login providers like Microsoft Account, Facebook, Google, etc.

The Identity API Uses the Cookies Authentication. Our tutorial Cookie Authentication in ASP.NET Core. shows how to implement Cookie authentication without identity. We recommend you read it first because the Identity system uses the same technique.

The Identity API contains a lot of helper classes, which hides the complexities of managing the users. It has classes to register users, authenticate them by validating their passwords, manage roles and claims etc. It also contains the login form, registration form, password reset forms, etc.

With ASP.NET Core Identity, you need not write any code, which helps you get started quickly in App Development.

What ASP.NET Core Identity System can do

  • Database schema for storing users, claims & Roles.
  • UI for logging in, creating, and managing users
  • Create/Modify/Delete User
  • Create/Modify/Delete User Claims
  • Password validation and rules.
  • Password Hashing
  • User account lockout
  • Generating password-reset tokens.
  • Multi Factor Authentication
  • Managing External Identity providers (for example Facebook, Google, Twitter).

ASP.NET Core Identity Architecture

ASP.NET Core Identity consists of two main category of classes. They are Managers & Stores.

Managers

The Managers manage the identity related data such as creating a user, adding roles, etc. It has classes like UserManager, RoleManager, SignInManager, etc.

User Manager

User Manager contains the methods to create, delete, update the users. It uses the stores to persist the data to the database

SignIn Manager

SignIn Manager is responsible for login and log out the user from the application. It contains the methods like SignInAsyncSignOutAsync etc. On Sign In, it creates a new ClaimsPrincipal from the User data. It sets the HttpContext.User property to the new ClaimsPrincipal. Then it serializes the principal, encrypts it, and stores it as a cookie.

This server sends cookie to the browser with the response. Browser returns it back to the server on every request.

Stores

Stores persists the users, roles, etc. to the data source.

The ASP.NET Core Identity API uses the Entity Framework Core to store the user information in SQL Server Database. But you can change it to use a different database or ORM

The Identity system decouples the Stores & Managers from each other. Hence, we can easily change the database providers without disrupting the entire application

The following diagram shows how your web application interacts with the managers and stores

Creating a Project with ASP.NET Core Identity

Create a new project in Visual Studio 2019. select the Template ASP.NET Core Web App. under the Authentication Type select Individual Accounts. Select Target Framework as .NET 5.0

Individual Accounts option installs the ASP.NET Core Identity with EF Core

Select Individual Accounts to install ASP.NET Core Identity

Setting Up Database

The Identity API uses the Entity Framework Core and SQL Server.

First, we need to update the connection string in ASP.NET Core. Open the appsettings.json and update the connection string to point to the correct database

appsettings.json

The Template includes add-migration script (Under Data folder). All you need to run the update-database to create the database

Package Manager Console

Now, open the SQL Server and explorer the tables.

ASP.NET Core Identity Database

The following tables shows the entity name, table name and their purpose

EntityTable NameRemarks
IdentityUserAspNetUsersPrimary table to store user information
IdentityUserClaimAspNetUserClaims tables holds the claims associated with the user.
IdentityUserLoginAspNetUserLogins table holds the information about 3rd party/external logins
IdentityUserTokenAspNetUserTokens is for storing tokens received from the external login providers.
IdentityUserRoleAspNetUserRoles table contains the roles assigned to the user
IdentityRoleAspNetRoles tables to store the roles
IdentityRoleClaimAspNetRoleClaims The claims that are assigned to the Role

Important table among them is AspNetUsers table.

AspNetUsers Table

Note that id field is a GUID column.

Running & Testing the Application

Once, the database is created and ready, you can run the App.

You will see the following screen.

ASP.NET Core Identity Welcome screen

Registering a new user

Click on Register Link to Register a new User. Note the URL /Identity/Account/Register

The Password is verified using the predefined configuration. You can change the password validation rules as per your apps requirements.

On successful registration the Identity API can send the Confirmation Email. But to do that we need to configure the email sender service. Otherwise, you will get the link to confirm the email in the registration confirmation screen

You can also use external service to Register the User. But to do that we need to configure them.

User Login

Clicking on the Login Link takes you to /Identity/Account/login URL.

Login Form allows us to login either providing the Email & Password or using the external providers (provided they are configured).

Option to reset a forgotten password is available in Login form. The API Also Provides the option to resend the confirmation mail.

User Profile

Once logged in the app will display the user name & logout menu link.

Click on the User name to open the Manage Account Screen. Here you will get options to

  1. Edit Your Profile
  2. Modify Email
  3. Change Password
  4. Enable Two-factor authentication
  5. Download or delete Personal data

Logout

Logout, will logs you out of the system.

Explore the Project

Now, let us look at the files installed by the Template

ASP.NET Core Identity Project Structure

IdentityDbContext

The Context class ApplicationDbContext is in the Data folder. The Data folder also contains the migrations for configuring the database.

The Code of the ApplicationDbContext is shown below.

Data/ApplicationDbContext.cs

The ApplicationDbContext inherits from the IdentityDbContext. which in turn inherits from the DBContext.

The IdentityDbContext contains the DbSet Properties for the IdentityRole, IdentityRoleClaim, IdentityUser, IdentityUserClaim, IdentityUserLogin, IdentityUserRole , IdentityUserToken Entities. You can find the properties of these entities from the Identity Entities.

Startup class

The ConfigureServices method of the startup class configures the identity & ApplicationDbContext related services.

Startup.cs

AddDefaultIdentity configures the Identity Services. You can make use of options to configure the behavior of the Identity API.

The AddEntityFrameworkStores configures the Identity to use the Entity Framework Core. We also need to specify the type of the Context that we are going to use to the Stores.

Authentication Middleware

The Identity API includes the Authentication middleware in the Middleware pipeline.

Authentication Middleware authenticates the user. We add it to the middleware pipeline by using the UseAuthentication  extension method.

One of the important task that is performed by the built-in authentication middleware is to read the cookies and construct the ClaimsPrincipal and update the User object in the HttpContext. The Authentication Middleware uses the Default Authentication Handler i.e. Cookie Authentication Handler to read the Cookies from the response and construct the ClaimsPrincipal

This will make the all the middleware’s which appear after the UseAuthentication() is aware that the user is authenticated.

We must invoke the UseAuthentication

  • After UseRouting, so that route information is available for authentication decisions.
  • Before UseEndpoints & UseAuthorization, so that users are authenticated before accessing the endpoints.

Startup.cs

Where is UI ?

All UI Forms are now part of the Razor class library in the namespace Microsoft.AspNetCore.Identity.UI. That is why you will not find them in Project. This is a new feature introduced in ASP.NET Core 2.1

Scaffold Identity UI in ASP.NET Core

The Identity Razor class library hides all the UI Forms, Services etc. But what if you want to modify or customize them. The ASP.NET Core provides an option to Scaffold the Identity UI and extract the source code and add it out project.

To do that,

  1. Right Click on Project
  2. Click Add
  3. Click New Scaffolded Item
Scaffold Identity UI in ASP.NET Core

In the Add New Scaffolded Item dialog box select Identity. Click on Add

Add New Scaffolded Item

This will bring you to Add Identity Dialog Box

  1. You can select a different layout page than the default.
  2. Override all files copies everything. You can also Import only those you need by selecting the individual item. For this tutorial select Override all files.
  3. Select the Data Context class, that you will be using for the identity. Select ApplicationDbContext from the drop down
  4. Also select the user class, if you overridden it in you application
  5. Click Add, when Finished
Add Identity Scaffold dialog box

The following files are added to the Project.

Identity Scaffolded Files

Examining the Code

Register Form

Areas/Identity/Pages/Accounts/Register.cshtml.cs

The Register form is decorated with AllowAnonymous so that anybody can access this page.

SignInManager and UserManager is injected into the Register Form

A new user is registered by clicking on the Register button, which will invoke the OnPostAsync method

Creating User

The UserManager.CreateAsync() method registers the new user

Sending Confirmation Email

GenerateEmailConfirmationTokenAsync() creates the Email Confirmation code. Using the code the Url.Page method generates the Email Confirmation link ( callbackUrl)

The Email Confirmation link (callbackUrl) is in the following format.

Where <id> is the Id of the User and the <code> is the Email Confirmation code.

SendEmailAsync sends the Confirmation mail with the above URL to the users email. The user is expected to click on the above link to confirm his account.

Note that mail is sent only if we have configure the email service. Since, we have not done it no email is sent for now.

Winding up

At this point user information is validated, stored in the database and email confirmation link is sent to his email box

But the account is not yet confirmed. Here we have two options depending the value of Options.SignIn.RequireConfirmedAccount

If the RequireConfirmedAccount is

  1. set to true, then the user is not logged in but re directed to Registration Confirmation page.
  2. set to false, then the user is automatically logged in without confirmation using the SignInAsync method.

RegisterConfirmation Form

The Identity API directs user the RegisterConfirmation Page after the successful registration provided the RequireConfirmedAccount is set true.

Areas/Identity/Pages/Accounts/RegisterConfirmation.cshtml

Ideally, this page should inform the user that he needs to confirm his email before login into the system.

But during testing or development, you might not have an email service set up. Hence the identity API provides displays the Email Confirmation link in this form. It allows us to confirm the account.

The code generates and displays the email confirmation link when DisplayConfirmAccountLink is true. You can click on the link and confirm your account

Remember to remove this code when you add a real email sender

Login Form

The Login form code is as follows.

Areas/Identity/Pages/Account/Login.cshtml.cs

AllowAnonymous decorator allows anyone to access the login form

When the form loads (OnGetAsync), it clears the existing external cookie by invoking the SignOutAsync method on the HTTPContext object.

It also loads the ExternalLogins so as to display them in the login screen.

OnPostAsync method is executes when the user clicks on login button.

It then calls the PasswordSignInAsync method with email & password to sign in the user.

The PasswordSignInAsync method does the following

  1. Verify the user exists and password matches
    1. Password / email does not match then returns with Succeeded set to false
    2. If 2 factor authentication enabled for the user, the returns with RequiresTwoFactor set to true
    3. In case user has exceeds the MaxFailedAccessAttempts, then is returns with IsLockedOut set true.
    4. If all is ok
      1. Creates the ClaimsIdentity with Claims of the User.
      2. Creates the ClaimsPrincipal from the ClaimsIdentity
      3. Invokes the HTTPContext.SignInAsync method with the ClaimsPrincipal and logs in the user.
      4. Returns with Succeeded set to true

If the PasswordSignInAsync returns Succeeded, then it redirect to the returnUrl and the user is logged in.

In the case of RequiresTwoFactor then the user is redirected to LoginWith2fa

If PasswordSignInAsync returns IsLockedOut then the Lockout URL is displayed to the user.

If fails to login then it displays the login failed error message.

Logout Form

Areas/Identity/Pages/Account/Logout.cshtml.cs

The logout calls the SignOutAsync to remove all cookies from the context.

Summary

This tutorial introduced you to ASP.NET Core Identity API. We showed how to create an ASP.NET Core web app using ASP.NET Core Identity for managing the User Accounts. Identity API hides the UI Forms from us. But you can scaffold them and add them to your project. We later looked at the register, login & logout form and learned how identity works under the hood.

3 thoughts on “Introduction to ASP.NET Core Identity”

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top