ASP.NET Core Identity Authentication Simplified
Tags: aspnet, identity, tools, excalidraw
Published: 2020-07-16 20:07:04

---
title: "ASP.NET Core Identity Authentication Simplified"
published: true
description: "A simplified glance at ASP.NET Core Identity authentication."
tags: ["ASPNET", "Identity", "Tools", "Excalidraw"]
canonical_url: https://kags.me.ke/post/asp-net-core-identity-authentication/
---

![Alt "asp.net core identity register and login sample screen drawn using Excalidraw"](https://dev-to-uploads.s3.amazonaws.com/i/5bwrh9xfki8ies8k92z7.png)

## Introduction

A first encounter with ASP.NET Core Identity seems intimidating. Add claims and third party login  providers  to the picture and most developers will opt for custom implementations for authentication and authorization.

By categorizing ASP.NET Core Identity functionality into local users, third party login providers and application roles, we reduce this complexity making ASP.NET Core Identity easier to work with.

In this article, we step create a project using ASP.NET Core Identity for authenticatin local users. We also extend the profile data for the application users without making any changes to the database table schema used by  ASP.NET Core Identity.

## Authentication - Prove You Are Who you Claim To Be

Authentication is the process of creating and letting users log in to an application based on their known credentials. These credentials could be their stored usernames and password or access tokens. Authentication does not determine what tasks the user can perform or what resources the user can see or access; it merely identifies and verifies who the user is. Passwords are the most common authentication method. If a user enters the correct user name and password, the system assumes the identity is valid and grants access to the application. A user, the user may be an individual or another application.

## What Is ASP.NET Core Identity

ASP.NET Core Identity is a user management system that provides various authentication and authorization services for ASP.NET Core applications. Some of these services include but not limited to the following:
- Inbuilt code for generation of database schemas for tables used for storing users, roles, claims and access tokens.
- Includes UI templates for authentication and authorizations processes
- Management of application authentication process for users 
- Strong user password hashing functionality 
- Generation of templates for password reset and email verification.
- Managing two factor authentication (2FA).
- Allows customization of any generated code
- Opt in for external login providers like Facebook, Twitter, Google, Microsoft and more

 By default, ASP.NET Core Identity uses Entity Framework (EF) Core to store user data in the database. It is however possible to swap out the EF Core and replace it with your own database integration libraries like Dapper.

## Claims - Extending User Profile Data

Properties associated with an application user are referred to as claims. These claims consist of a type and a value. A claim may contain multiple values and an identity can contain multiple claims of the same type.

Aside from user name, email and  password, an application may require storing of other user claims such as whether the user is active, the role of a user within an organization, display name for a user, date of last login and many more.You can extend the profile application users by appending more claims to the application users.

## Show me the Code
In the article we create and work with a project named **RazorAuthSample** using Visual Studio Code.

Run `dotnet new razor --auth Individual -o RazorAuthSample` command from a terminal window to create the project. When the project has been created, change directory to *RazorAuthSample* folder `cd RazorAuthSample` and run `code .` to open the project using Visual Studio Code.

![Alt "New project with authentication folder structure"](https://dev-to-uploads.s3.amazonaws.com/i/fthua7tu9nuty9wsndgr.png)

After the project has been created,  *Startup.cs* file will be updated with the following changes:

- Additional configuration will be introduced within the **ConfigureServices** method to add services that Identity requires. `AddDefaultIdentity<IdentityUser>` will add the Identity system and configure the user type. `AddEntityFrameworkStores<ApplicationDbContext>()` will configure Identity to store its data in Entity Framework Core.

{% gist https://gist.github.com/kagundajm/59c7360f323e0a222f8ba534e038ec4f %}

- `app.UseAuthentication();` middleware will be added within **Configure** method just before authorization. This middleware will allow authentication  of incoming requests. Placement of the **UseAuthentication** middleware is early within the middlewares pipeline to prevent non-authenticated users from accessing content requiring authentication. 

{% gist https://gist.github.com/kagundajm/be69aada004bef14076852954c8966d5 %}

## The 7 ASP.NET Core Identity Tables

![Alt "asp.net core identity tables"](https://dev-to-uploads.s3.amazonaws.com/i/cqlcwup2d2dq3bn9dinb.png)

When using SQLite, the data migrations are applied upon creation of the project. If using a different database, you need to run `dotnet ef database update` to update the database with the migrations.

ASP.NET Core Identity has a total of seven tables prefixed with **AspNet**. The tables can be broken down into the following three groups:
1. **User and User Claims management**. In this group  are two (2) tables; **AspNetUsers** and **AspNetUserClaims**. **AspNetUsers** table stores profile data for the user while **AspNetUserClaims**  stores claims associated with an application user. If your application is managing users and their passwords without using any external third party identity providers (like Facebook, Twitter, Google, Microsoft, etc ), these are the only tables you may require for identity management.

2. **Third Party Identity Provider Tables**. If you want to delegate authentication for your application to third party providers (for example Facebook, Twitter, Google, Microsoft), then **AspNetUserLogins** and **AspNetUserTokens** are the tables you may be interested in. By using a third party identity provider, you shift responsibility and any risk of storing users’ personal data onto the third party. You can combine third party authentication with application based authentication as a fallback plan just in case the external login provider may become unavailable.

3. **Role Based Identity Tables**. In role based authentication, a user must be assigned to a role and any application permissions assigned to an application role. If your application uses this model for authentication, then the following three (3) tables will be necessary; **AspNetUserRoles**, **AspNetRoles**, and **AspNetRoleClaims**. The role-based permission model is considered to be legacy and use of claims-based permission model is encouraged. 

You are not restricted to the group of tables your application should adopt for the identity model. It is possible to use one or more of the above groups for identity management. For this article, we will work only with only users and user claims.

The schema of some tables contain columns with names prefixed with **Normalized** keyword. Any data in these normalized columns is all set in uppercase. For example **NormalizedEmail** column will contain similar data to **Email** column but in uppercase. 

So what is the purpose of these normalized columns?. [The Github repository code issues contains an explaination for the purpose of the normalized columns.](https://github.com/dotnet/AspNetCore.Docs/issues/16774#issuecomment-580378264)
>> The normalized fields are what we do comparisons against for lookups, the regular columns are what you can think of as the display names, so the casing is preserved.

## Install Entity Framework (EF) Core Tool and Shared Components
 Verify whether Entity Framework Core tool installed by running `dotnet tool list -g`. If the output of the command does not contain an entry for `dotnet-ef`, then install EF Core tool by running `dotnet tool install --global dotnet-ef`. 

Install design-time shared components for Entity Framework Core tools by running `dotnet add package Microsoft.EntityFrameworkCore.Design`. These components are necessary  for using commands  like `dotnet ef`

## Configure password, lockout and user settings . 
This step is optional if you want to use the default settings. You have however to be aware that even after successfully registering a new user, the new user cannot login until the user's email has been verified. You can disable this requirement by setting **RequireConfirmedAccount** to false `services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)` within the **ConfigureServices** method in *Startup.cs*.

Apart from **RequireConfirmedAccount**, other password default settings that you may require to modify are that passwords contain an uppercase character, lowercase character, a digit, and a non-alphanumeric character. The password length is set by default to be at least six characters long. You can modify this value to either increase or reduce the length.

You can also configure lockout, user and cookie settings to fit your environment.

{% gist https://gist.github.com/kagundajm/8570f4aa6560aae90da9ef6195c03112 %}

## Scaffold Identity register, login and logout UI pages.
Scaffolding will allow you to generate code used for the identity features you may require. In this article we scaffold code for registration, login and logout features. After the code has been generated, you can then modify the code to fit your needs. 

Before scaffolding, verify that ASP.NET Core scaffolder tool is installed by running `dotnet tool list -g`. If the output from the command does not contain an entry for `dotnet-aspnet-codegenerator`, then install EF Core tool by running `dotnet tool install -g dotnet-aspnet-codegenerator` command.

Next, add **Microsoft.VisualStudio.Web.CodeGeneration.Design** NuGet package to the project by running `dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design` command. 

Even though we are using SQLite database in our project, at the time of this writing, SQLite requires [Microsoft SQL Server database provider EntityFrameworkCore package](https://github.com/dotnet/AspNetCore.Docs/issues/14740#issuecomment-566287853) to be installed. To install **Microsoft.EntityFrameworkCore.SqlServer** package, run `dotnet add package Microsoft.EntityFrameworkCore.SqlServer` command.

Scaffold register, login and logout code by running `dotnet aspnet-codegenerator identity -dc RazorAuthSample.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.Logout"` command. **-dc** option refers to the application DbContext to use. Replace **RazorAuthSample.Data.ApplicationDbContext** with the location of your application's ApplicationDbContext file. Omitting **--files** generator option will generate all available Identity UI pages.

##  Extend User Profile Data

The generated identity register user UI page contains only email and password input fields. Likewise, **AspNetUsers** table schema contains columns for username, email, phone number and hashed password. You can capture more details for the application user by adding these to the collection of user claims.

The process of customizing the new identity user with the new properties can be accomplished using three steps. Let's demonstrate the steps by extending the user registration page to include first name and a check of whether the user being created is an administrator.

1. Start by adding the new properties to the **InputModel** class. Open *Areas/Identity/Pages/Account/Register.cshtml.cs* page model and update **InputModel** class to include **FirstName** and **IsAdmin** properties.

{% gist https://gist.github.com/kagundajm/913c8c50059165b1613dfca9beb7e245 %}

2. Next, update *Register.cshtml* page with the new input fields. Open *Areas/Identity/Pages/Account/Register.cshtml* page and insert new input fields for the new properties.

{% gist https://gist.github.com/kagundajm/f0c8c8563acc959f06379847dec28795 %}

3. Open *Register.cshtml.cs* and update the code for creating the new user to add **FirstName** and **IsAdmin** properties to the user claims collection. Add `using System.Security.Claims;` namespace to the page model namespaces and insert following code to persist and append **FirstName** and **IsAdmin** properties to the user claims collection.

{% gist https://gist.github.com/kagundajm/f7f9b1dcd96c1a1f53e5ccfaf43d5e9d %}

## Testing the Application

Run the application by pressing **Control + F5** keys or by selecting **Run** > **Run Without Debugging** from the menu. When the application displays on a web browser, click on **Register** link (top right) to register a new user and type the user data. Click on **Register** button to persist the user data. On the **Registration confirmation** page, click on **Click here to confirm your account** link to confirm the user's email. After email confirmation, click on **Login** link (top right). Type email and password used on registration and click on **Log in** button.

![Alt "Extended identity user registration page"](https://dev-to-uploads.s3.amazonaws.com/i/hf4mrcd865rk37bkccsy.png)

You can display any of the claims you have added anywhere on a razor page by using `@User.FindFirstValue` method and providing the claim type you are interested in. For example, 
to display the **FirstName** claim in place of the email address after successfull registration and login, replace `@User.Identity.Name` in the *_LoginPartial.cshtml* with `@User.FindFirstValue("FirstName")`. Remember to add `@using System.Security.Claims` namespace in the  *_LoginPartial.cshtml* page namespaces.  Alternatively, you can use LINQ to fetch a user claim `@User.Claims.FirstOrDefault(x=>x.Type == "FirstName").Value`. Using this latter approach does not require importation of the `@using System.Security.Claims` namespace on a razor page.

## Conclusion

In this article, we went through the process of using ASP.NET Core Identity for user authentication by creating a sample application using Visual Studio Code. By grouping tables used with ASP.NET Core Identity, we noted it is possible to simplify the workings of ASP.NET Core Identity Using claims, we observed that we can extend the profile data for a user and utilize that data within our application without making modifications to the default tables provided by ASP.NET Core Identity.

## Resources

- [Introduction to Identity on ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity)
- [Scaffold Identity in ASP.NET Core projects](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-3.1&tabs=netcore-cli)
- Tools
    - [Beekeeper Studio](https://www.beekeeperstudio.io/)
    - [Excalidraw](https://github.com/excalidraw/excalidraw)