Using Identity In ASP.NET Core MVC Authentication

Introduction


This article explains how to get started with Identity.UI in ASP.Net Core MVC user authentication and registration.

Link to download the project source code here.

Step 1
 
Let's create an ASP.NET Core web application. Open Visual Studio 2019 and click on Create a new project.
 
 
 
Select ASP.NET Core Web Application, and click on Next 
 
 
Provide the project name of your choice, select the preferred location & click on Create

 
Select MVC Template and click on create, as shown below:

Step 2
 
Now let's add an ASP.NET Core Identity. Select the project > Right-click > Add > click on New Scaffold item 
 
 
Select Identity and click on add
 
 
Now select the layout page, as we want authentication. Let's select login and Register as shown below and provide DbContext class and user class and click on Add

 
We can find the Areas in the application with Data & Razor pages, as shown below:

 
Step 3
 
Now let's add user authentication to the application. Open the Startup class and Modify as shown below.

In order to add support to the razor pages, we have to call the function services.AddRazorPages() and endpoints.MapRazorPages()
  1. public class Startup  
  2.    {  
  3.        public Startup(IConfiguration configuration)  
  4.        {  
  5.            Configuration = configuration;  
  6.        }  
  7.   
  8.        public IConfiguration Configuration { get; }  
  9.   
  10.        // This method gets called by the runtime. Use this method to add services to the container.  
  11.        public void ConfigureServices(IServiceCollection services)  
  12.        {  
  13.            services.AddControllersWithViews();  
  14.            services.AddRazorPages();  
  15.        }  
  16.   
  17.        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
  18.        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
  19.        {  
  20.            if (env.IsDevelopment())  
  21.            {  
  22.                app.UseDeveloperExceptionPage();  
  23.            }  
  24.            else  
  25.            {  
  26.                app.UseExceptionHandler("/Home/Error");  
  27.                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.  
  28.                app.UseHsts();  
  29.            }  
  30.            app.UseHttpsRedirection();  
  31.            app.UseStaticFiles();  
  32.   
  33.            app.UseRouting();  
  34.            app.UseAuthentication();  
  35.   
  36.            app.UseAuthorization();  
  37.   
  38.            app.UseEndpoints(endpoints =>  
  39.            {  
  40.                endpoints.MapControllerRoute(  
  41.                    name: "default",  
  42.                    pattern: "{controller=Home}/{action=Index}/{id?}");  
  43.                endpoints.MapRazorPages();  
  44.            });  
  45.        }  
  46.    }  
Step 4
 
Now let's start with creating the database for the application.

Open UsingIdentityUser class and add the properties and decorate with the attribute PersonalData.
  1. public class UsingIdentityUser : IdentityUser  
  2.    {  
  3.        [PersonalData]  
  4.        [Column(TypeName ="nvarchar(100)")]  
  5.        public string Firstname { getset; }  
  6.        [PersonalData]  
  7.        [Column(TypeName = "nvarchar(100)")]  
  8.        public string LastName { getset; }  
  9.    }  
We have Dbcontext, which is also inherited from the parent class IdentityDB context. This identity db context is injected inside this identityhostingstartup class.
  1. public class IdentityHostingStartup : IHostingStartup  
  2.    {  
  3.        public void Configure(IWebHostBuilder builder)  
  4.        {  
  5.            builder.ConfigureServices((context, services) => {  
  6.                services.AddDbContext<UsingIdentityContext>(options =>  
  7.                    options.UseSqlServer(  
  8.                        context.Configuration.GetConnectionString("UsingIdentityContextConnection")));  
  9.   
  10.                services.AddDefaultIdentity<UsingIdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)  
  11.                    .AddEntityFrameworkStores<UsingIdentityContext>();  
  12.            });  
  13.        }  
  14.    }  
Now open appsttings.json. We can find the connection string with the name UsingIdentityContextConnection. By default, it will connect to the local DB.
  1. {  
  2.   "Logging": {  
  3.     "LogLevel": {  
  4.       "Default""Information",  
  5.       "Microsoft""Warning",  
  6.       "Microsoft.Hosting.Lifetime""Information"  
  7.     }  
  8.   },  
  9.   "AllowedHosts""*",  
  10.   "ConnectionStrings": {  
  11.     "UsingIdentityContextConnection""Server=SAGAR;Database=UsingIdentityDB;Trusted_Connection=True;MultipleActiveResultSets=true"  
  12.   }  
  13. }  
Now open the Package manager console and Execute the command Add-Migration "First-Create" to generate the actual physical DB 
 
 
Finally, execute the command Update-Database and you can find the new database as shown below.

                     
 
Step 5
 
Now let's start customizing the application. Let's add a Nested layout for tab control headers.
 
 
Select Razor layout and click on Add



Customize the layout as below
  1. @{    
  2.     Layout = "/Views/Shared/_Layout.cshtml";    
  3. }    
  4. <div class="row">    
  5.     <div class="col-md-6  offset-md-3">    
  6.         <div class="card login-logout-tab">    
  7.             <div class="card-header">    
  8.                 <ul class="nav nav-tabs card-header-tabs">    
  9.                     <li class="nav-item">    
  10.     
  11.                         <a class="nav-link" href="/Identity/Account/Login">Log In</a>    
  12.                     </li>    
  13.                     <li class="nav-item">    
  14.     
  15.                         <a class="nav-link" href="/Identity/Account/Register">Sign Up </a>    
  16.                     </li>    
  17.                 </ul>    
  18.             </div>    
  19.             <div class="card-content">    
  20.     
  21.                 <div class="row">    
  22.                     <div class="col-md-12 ">    
  23.                         @RenderBody()    
  24.                     </div>    
  25.                 </div>    
  26.             </div>    
  27.     
  28.         </div>    
  29.     </div>    
  30. </div>    
  31. @section Scripts{    
  32.     
  33.     @RenderSection("Scripts", required: false)    
  34.     <script>    
  35.         $(function () {    
  36.     
  37.             var current = location.pathname;    
  38.             $('.nav-tabs li a').each(function () {    
  39.                 var $this = $(this);    
  40.                 if (current.indexOf($this.attr('href')) !== -1) {    
  41.                     $this.addClass('active');    
  42.                 }    
  43.             })    
  44.         })    
  45.     </script>    
  46. }    
Open site.css and use the below styles
  1. /*for Tab control*/  
  2. div.login-logout-tab div.card.header{  
  3.     padding0px 0px 12px 0px;  
  4. }  
  5. div.login-logout-tab li.nav-tabs{  
  6.   
  7.     margin0px 0px -12px 0px;  
  8. }  
  9. div.login-logout-tab li.nav-item{  
  10.   
  11.     width:50%  
  12. }  
  13. div.login-logout-tab a.nav-link{  
  14.     font-size:25px;  
  15.     color:#495057;  
  16.     text-align:center;  
  17. }  
Modify the Login page and register the HTML pages with our new layout. 
  1. @page    
  2. @model LoginModel    
  3.     
  4. @{    
  5.     ViewData["Title"] = "Log in";    
  6.     Layout = "~/Areas/Identity/Pages/_IdentityLayout.cshtml";    
  7. }    
  8.     
  9. <div class="col-md-10 offset-md-1">    
  10.     <section>    
  11.         @*<div class="login-form-icon">    
  12.             <i class="fas fa-user-circle fa-5x text-secondary"></i>    
  13.         </div>*@    
  14.         @*fas fa-user-circle fa-9x text-secondary*@    
  15.         <form id="account" method="post">    
  16.             <div asp-validation-summary="All" class="text-danger"></div>    
  17.             <div class="form-group">    
  18.                 <label asp-for="Input.Email"></label>    
  19.                 <input asp-for="Input.Email" class="form-control" />    
  20.                 <span asp-validation-for="Input.Email" class="text-danger"></span>    
  21.             </div>    
  22.             <div class="form-group">    
  23.                 <label asp-for="Input.Password"></label>    
  24.                 <input asp-for="Input.Password" class="form-control" />    
  25.                 <span asp-validation-for="Input.Password" class="text-danger"></span>    
  26.             </div>    
  27.             <div class="form-group">    
  28.                 <div class="checkbox">    
  29.                     <label asp-for="Input.RememberMe">    
  30.                         <input asp-for="Input.RememberMe" />    
  31.                         @Html.DisplayNameFor(m => m.Input.RememberMe)    
  32.                     </label>    
  33.                 </div>    
  34.             </div>    
  35.             <div class="form-group">    
  36.                 <button type="submit" class="btn btn-primary btn-block">Log in</button>    
  37.             </div>    
  38.         </form>    
  39.     
  40.     </section>    
  41. </div>    
  42.     
  43. @section Scripts {    
  44.     <partial name="_ValidationScriptsPartial" />    
  45. }    
  46.   
  47. @page    
  48. @model RegisterModel    
  49. @{    
  50.     ViewData["Title"] = "Register";    
  51.     Layout = "~/Areas/Identity/Pages/_IdentityLayout.cshtml";    
  52. }    
  53.     
  54. <h1>@ViewData["Title"]</h1>    
  55.     
  56.     
  57. <form asp-route-returnUrl="@Model.ReturnUrl" method="post">    
  58.     <div asp-validation-summary="All" class="text-danger"></div>    
  59.     <div class="row">    
  60.         <div class="col-md-6">    
  61.             <div class="form-group">    
  62.                 <label asp-for="Input.FirstName"></label>    
  63.                 <input asp-for="Input.FirstName" class="form-control" />    
  64.                 <span asp-validation-for="Input.FirstName" class="text-danger"></span>    
  65.             </div>    
  66.         </div>    
  67.     
  68.         <div class="col-md-6">    
  69.             <div class="form-group">    
  70.                 <label asp-for="Input.LastName"></label>    
  71.                 <input asp-for="Input.LastName" class="form-control" />    
  72.                 <span asp-validation-for="Input.LastName" class="text-danger"></span>    
  73.             </div>    
  74.         </div>    
  75.     </div>    
  76.     <div class="row">    
  77.         <div class="col-md-6">    
  78.             <div class="form-group">    
  79.                 <label asp-for="Input.Email"></label>    
  80.                 <input asp-for="Input.Email" class="form-control" />    
  81.                 <span asp-validation-for="Input.Email" class="text-danger"></span>    
  82.             </div>    
  83.         </div>    
  84.         <div class="col-md-6">    
  85.             <div class="form-group">    
  86.                 <label asp-for="Input.PhoneNumber"></label>    
  87.                 <input asp-for="Input.PhoneNumber" class="form-control" />    
  88.                 <span asp-validation-for="Input.PhoneNumber" class="text-danger"></span>    
  89.             </div>    
  90.         </div>    
  91.     </div>    
  92.         
  93.     <div class="row">    
  94.         <div class="col-md-6">    
  95.             <div class="form-group">    
  96.                 <label asp-for="Input.Password"></label>    
  97.                 <input asp-for="Input.Password" class="form-control" />    
  98.                 <span asp-validation-for="Input.Password" class="text-danger"></span>    
  99.             </div>    
  100.         </div>    
  101.         <div class="col-md-6">    
  102.             <div class="form-group">    
  103.                 <label asp-for="Input.ConfirmPassword"></label>    
  104.                 <input asp-for="Input.ConfirmPassword" class="form-control" />    
  105.                 <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>    
  106.             </div>    
  107.         </div>    
  108.     </div>    
  109.     
  110.     <button type="submit" class="btn btn-primary">Register</button>    
  111. </form>    
  112.     
  113. @section Scripts {    
  114.     <partial name="_ValidationScriptsPartial" />    
  115. }    
In order to display the active tab, we need to add an active class, as shown below.
  1. @section Scripts{  
  2.   
  3.     @RenderSection("Scripts", required: false)  
  4.     <script>  
  5.         $(function () {  
  6.   
  7.             var current = location.pathname;  
  8.             $('.nav-tabs li a').each(function () {  
  9.                 var $this = $(this);  
  10.                 if (current.indexOf($this.attr('href')) !== -1) {  
  11.                     $this.addClass('active');  
  12.                 }  
  13.             })  
  14.         })  
  15.     </script>  
  16. }  
Let's see the output and register a user.

 
Now let's login with the registered user.

 
 

Conclusion


In this article, we discussed how to use Identity UI in ASP.NET Core MVC application by creating a database using the package manager console & commands. I hope you all enjoyed reading this and learned from it.