Click here to Skip to main content
15,880,608 members
Articles / Security

Identity-Based Authentication in .NET Core 3.0 using In-Memory Database

Rate me:
Please Sign up or sign in to vote.
4.53/5 (4 votes)
31 Jan 2020CPOL4 min read 22.2K   284   14   3
This article demonstrates how to add Identity-Based Authentication in .NET Core 3.0 using In-Memory Database.

Introduction

Authentication is the process of determining or giving an individual access to system or user based on their identity. There are multiple options to do authentication in .NET Core. This article demonstrates how to add Identity-Based Authentication in .NET Core 3.0 using In-Memory Database.

Background

In the previous article, I explained about Cookie-Based Authentication In .NET Core 3.0.

Prerequisites

  • Install .NET Core 3.0.0 or above SDK from here.
  • Install the latest version of Visual Studio 2019 Community Edition from here.

Steps for Creating a Web Application

  1. Go to Visual Studio 2019, then select Create a new project from option list.

    Image 1

  2. After selecting that, a new window will open to select project template.
  3. Select “ASP.NET Core Web Application” and click on Next button.

    Image 2

  4. A new screen will open to configure your new project. Provide Project Name, Location, Solution Name as per your requirement. Press Create button.

    Image 3

  5. After clicking on Create button, a new screen will open to configure your project related information like which environment you want to create for web application? .NET Framework or .NET Core. Select .NET Core and ASP.NET Core Version from drop down list. Then, select web application (Model-View-Controller) option from list and press Create button to create a project.

    Image 4

  6. Now our project will open with the basic structure of .NET Core environment. You can observe in the solution explorer that will have Controllers, Models and Views folders with “Startup.cs” and other files as well like the below image:

    Image 5

  7. Run your application to check whether the created web application is running fine or not. By default, it will open a Home page (Index page of Home controller) of your project.

Install the below NuGet of version 3.0.0 or latest

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.InMemo
  • Microsoft.EntityFrameworkCore.Identity.EntityFrameworkCore

Integrate Identity Authentication

  1. IdentityDbContext: Provide all DbSet properties which are required to manage the identity tabels
  2. ApplicationDbContext: User defined DbContext class inherits from IdentityDbContext to manage the user identity
  3. UseInMemoryDatabase: To store the user information for identity in memory instead of using any database
  4. AppUser: User defined class inherits from IdentityUser to add extra properties of user
  5. UserManager: To manage user information like create user information, delete user information
  6. SignInManager: Handle the communication with HttpContext as well as the user signin or signout functionality
  7. [Authorize]: Attribute helps to validate user to an access controller (User Information)

Step 1

Create a new folder with name as Data and add ApplicationDbContext into it and put the below lines of code into it:

C#
using DemoIdentityAuthentication.Models;  
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;  
using Microsoft.EntityFrameworkCore;  
  
namespace DemoIdentityAuthentication.Data  
{  
    // IdentityDbContext contains all the user tables  
    public class ApplicationDbContext : IdentityDbContext<AppUser>  
    {  
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)  
            : base(options)  
        {  
        }  
    }  
}  

Step 2

Add a new class into Models folder with name AppUser and put the below lines of code into it:

C#
using Microsoft.AspNetCore.Identity;  
  
namespace DemoIdentityAuthentication.Models  
{  
    public class AppUser : IdentityUser  
    {  
        public string Name { get; set; }  
        public string DateOfBirth { get; set; }  
        public string Password { get; set; }  
    }  
}

Step 3

Changes in Startup.cs file:

C#
using DemoIdentityAuthentication.Data;  
using DemoIdentityAuthentication.Models;  
using Microsoft.AspNetCore.Builder;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.AspNetCore.Identity;  
using Microsoft.EntityFrameworkCore;  
using Microsoft.Extensions.Configuration;  
using Microsoft.Extensions.DependencyInjection;  
using Microsoft.Extensions.Hosting;  
using System;  
  
namespace DemoIdentityAuthentication  
{  
    public class Startup  
    {  
        public Startup(IConfiguration configuration)  
        {  
            Configuration = configuration;  
        }  
  
        public IConfiguration Configuration { get; }  
  
        public void ConfigureServices(IServiceCollection services)  
        {  
            services.AddDbContext<ApplicationDbContext>(config =>  
            {  
                // for in memory database  
                config.UseInMemoryDatabase("MemoryBaseDataBase");  
            });  
  
            // AddIdentity :-  Registers the services  
            services.AddIdentity<AppUser, IdentityRole>(config =>  
            {  
                // User defined password policy settings.  
                config.Password.RequiredLength = 4;  
                config.Password.RequireDigit = false;  
                config.Password.RequireNonAlphanumeric = false;  
                config.Password.RequireUppercase = false;  
            })  
                .AddEntityFrameworkStores<ApplicationDbContext>()  
                .AddDefaultTokenProviders();  
  
            // Cookie settings   
            services.ConfigureApplicationCookie(config =>  
            {  
                config.Cookie.Name = "DemoProjectCookie";  
                config.LoginPath = "/Home/Login"; // User defined login path  
                config.ExpireTimeSpan = TimeSpan.FromMinutes(5);  
            });   
  
            services.AddControllersWithViews();  
        }  
  
        // This method gets called by the runtime. 
        // Use this method to configure the HTTP request pipeline.  
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
        {  
            if (env.IsDevelopment())  
            {  
                app.UseDeveloperExceptionPage();  
            }  
            else  
            {  
                app.UseExceptionHandler("/Home/Error");  
                // The default HSTS value is 30 days. 
                // You may want to change this for production scenarios, 
                // see https://aka.ms/aspnetcore-hsts.  
                app.UseHsts();  
            }  
            app.UseHttpsRedirection();  
            app.UseStaticFiles();  
  
            app.UseRouting();  
  
            app.UseAuthentication();  
  
            app.UseAuthorization();  
  
            app.UseEndpoints(endpoints =>  
            {  
                endpoints.MapControllerRoute(  
                    name: "default",  
                    pattern: "{controller=Home}/{action=Index}/{id?}");  
            });  
        }  
    }  
}

Step 4

Update HomeController with New Action Methods:

  1. Login: For user login
  2. Register: For registering a new user
  3. Logout: To logout current user
  4. UserInfo with Authorize tag: To display user information for valid user and restrict to get an access for invalid user

Put the below lines of code into HomeController:

C#
using System;  
using System.Collections.Generic;  
using System.Diagnostics;  
using System.Linq;  
using System.Threading.Tasks;  
using Microsoft.AspNetCore.Mvc;  
using Microsoft.Extensions.Logging;  
using DemoIdentityAuthentication.Models;  
using Microsoft.AspNetCore.Identity;  
using Microsoft.AspNetCore.Authorization;  
  
namespace DemoIdentityAuthentication.Controllers  
{  
    public class HomeController : Controller  
    {  
        private readonly UserManager<AppUser> _userManager;  
        private readonly SignInManager<AppUser> _signInManager;  
        public HomeController(  
                   UserManager<AppUser> userManager,  
                   SignInManager<AppUser> signInManager)  
        {  
            _userManager = userManager;  
            _signInManager = signInManager;  
        }  
  
        public IActionResult Index()  
        {  
            return View();  
        }    
  
        [Authorize]  
        public async Task<IActionResult> UserInfo()  
        {  
            var user = 
                await _userManager.GetUserAsync(HttpContext.User).ConfigureAwait(false);            
  
            if (user == null)  
            {  
                RedirectToAction("Login");  
            }  
            //login functionality  
  
            return View(user);  
        }  
  
        [HttpGet]  
        public IActionResult Login()  
        {  
            return View();  
        }  
  
        [HttpPost]  
        public async Task<IActionResult> Login(AppUser appUser)  
        {  
  
            //login functionality  
            var user = await _userManager.FindByNameAsync(appUser.UserName);  
  
            if (user != null)  
            {  
                //sign in  
                var signInResult = await _signInManager.PasswordSignInAsync
                                   (user, appUser.Password, false, false);  
  
                if (signInResult.Succeeded)  
                {  
                    return RedirectToAction("Index");  
                }  
            }  
  
            return RedirectToAction("Register");  
        }  
  
        public IActionResult Register()  
        {  
            return View();  
        }  
  
        [HttpPost]  
        public async Task<IActionResult> Register(AppUser appUser)
        {  
            //register functionality  
  
            var user = new AppUser  
            {  
                Id = "101",  
                UserName = appUser.UserName,  
                Email = appUser.Email,  
                Name = appUser.Name,  
                DateOfBirth = appUser.DateOfBirth,  
                Password = appUser.Password  
            };  
  
            var result = await _userManager.CreateAsync(user, user.Password);  
  
  
            if (result.Succeeded)  
            {  
                // User sign  
                // sign in   
                var signInResult = await _signInManager.PasswordSignInAsync
                                   (user, user.Password, false, false);
  
                if (signInResult.Succeeded)  
                {  
                    return RedirectToAction("Index");  
                }  
            }  
  
            return View();  
        }  
  
        public async Task<IActionResult> LogOut(string username, string password)
        {  
            await _signInManager.SignOutAsync();  
            return RedirectToAction("Index");  
        }  
    }  
} 

Step 5

Add view for HomeController:

  1. Go to Views folder and select Home folder.
  2. Right click on the Home folder to select add option and select view.
  3. A window popup will open to add View.
  4. Provide View name as Login, select Template as Empty, select Use a layout page and press Add button. A new Login.cshtml file will create into Home folder. Refer to the image below to add view:

    Image 6

  5. Follow the same steps for other views as well and create a view for UserInfo action and Register action as well.
  6. Code for the Login.cshtml page:
    HTML
    @model DemoIdentityAuthentication.Models.AppUser  
      
    <h1>User Login</h1>  
      
    <form asp-controller="Home" asp-action="Login">  
        <div class="form-group col-sm-6">  
            <label for="Username">Username</label>  
            <input type="text" class="form-control" 
            id="Username" asp-for="UserName" 
                   placeholder="Enter username">  
        </div>  
        <div class="form-group col-sm-6">  
            <label for="Password">Password</label>  
            <input type="password" class="form-control" id="Password" 
                    asp-for="Password" placeholder="Enter password">  
        </div>  
        <div class="form-group col-sm-6">  
            <button type="submit" class="btn btn-primary">Login</button>  
        </div>  
    </form>  

    Image 7

    HTML
    @model DemoIdentityAuthentication.Models.AppUser  
      
    @{  
        ViewData["Title"] = "Register";  
    }  
      
    <h1>User Register</h1>  
      
    <form method="post" asp-controller="Home" asp-action="Register">  
        <div class="form-group col-sm-6">  
            <label for="Name">Name</label>  
            <input type="text" class="form-control" 
            id="Name" asp-for="Name" placeholder="Enter name">  
        </div>  
      
        <div class="form-group col-sm-6">  
            <label for="EmailId">Email Id</label>  
            <input type="email" class="form-control" 
            id="EmailId" asp-for="Email" placeholder="Enter email id">  
        </div>  
      
        <div class="form-group col-sm-6">  
            <label for="Username">Username</label>  
            <input type="text" class="form-control" 
            id="Username" asp-for="UserName" placeholder="Enter username">  
        </div>  
        <div class="form-group col-sm-6">  
            <label for="Password">Password</label>  
            <input type="password" class="form-control" 
            id="Password" asp-for="Password" placeholder="Enter password">  
        </div>  
        <div class="form-group col-sm-6">  
            <label for="DOB">Date Of Birth</label>  
            <input type="text" class="form-control" 
            id="DOB" asp-for="DateOfBirth" placeholder="Enter date of birth">  
        </div>  
        <div class="form-group col-sm-6">  
            <button type="submit" class="btn btn-primary">Register</button>  
        </div>  
    </form>  
  7. Code for the UserInfo.cshtml page:
    HTML
    @model DemoIdentityAuthentication.Models.AppUser  
      
    <h1>User Information</h1>  
      
    <table>  
        <tr>  
            <td>Name:- </td>  
            <td>@Html.DisplayFor(model => model.Name)</td>  
        </tr>  
        <tr>  
            <td>Email:- </td>  
            <td>@Html.DisplayFor(model => model.Email)</td>  
        </tr>  
        <tr>  
            <td>Username:- </td>  
            <td>@Html.DisplayFor(model => model.UserName)</td>  
        </tr>  
        <tr>  
            <td>Date Of Birth:- </td>  
            <td>@Html.DisplayFor(model => model.DateOfBirth)</td>  
        </tr>  
    </table>  

Step 6

Update _Layout.cshtml page to add new tab/hyperlink for User Login, User Registration, User Information and for User Logout.

Code for _Layout.cshtml is as follows:

HTML
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="utf-8" />  
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />  
    <title>@ViewData["Title"] - DemoIdentityAuthentication</title>  
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />  
    <link rel="stylesheet" href="~/css/site.css" />  
</head>  
<body>  
    <header>  
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm 
        navbar-light bg-white border-bottom box-shadow mb-3">  
            <div class="container">  
                <a class="navbar-brand" asp-area="" 
                asp-controller="Home" 
                asp-action="Index">DemoIdentityAuthentication</a>  
                <button class="navbar-toggler" type="button" 
                data-toggle="collapse" data-target=".navbar-collapse" 
                aria-controls="navbarSupportedContent"  
                        aria-expanded="false" aria-label="Toggle navigation">  
                    <span class="navbar-toggler-icon"></span>  
                </button>  
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">  
                    <ul class="navbar-nav flex-grow-1">  
                        <li class="nav-item">  
                            <a class="nav-link text-dark" asp-area="" 
                            asp-controller="Home" asp-action="Index">Home</a>  
                        </li>  
                        <li class="nav-item">  
                            <a class="nav-link text-dark" asp-area=""
                            asp-controller="Home" asp-action="Register">Register</a>  
                        </li>  
                        <li class="nav-item">  
                            <a class="nav-link text-dark" asp-area="" 
                            asp-controller="Home" asp-action="Login">Login</a>  
                        </li>  
                        <li class="nav-item">  
                            <a class="nav-link text-dark" asp-area="" 
                            asp-controller="Home" 
                            asp-action="UserInfo">User Information</a>  
                        </li>  
                        <li class="nav-item">  
                            <a class="nav-link text-dark" asp-area="" 
                            asp-controller="Home" asp-action="Logout">Logout</a>  
                        </li>  
                    </ul>  
                </div>  
            </div>  
        </nav>  
    </header>  
    <div class="container">  
        <main role="main" class="pb-3">  
            @RenderBody()  
        </main>  
    </div>  
  
    <footer class="border-top footer text-muted">  
        <div class="container">  
            © 2020 - DemoIdentityAuthentication - <a asp-area="" 
            asp-controller="Home" asp-action="Privacy">Privacy</a>  
        </div>  
    </footer>  
    <script src="~/lib/jquery/dist/jquery.min.js"></script>  
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>  
    <script src="~/js/site.js" asp-append-version="true"></script>  
    @RenderSection("Scripts", required: false)  
</body>  
</html>  

Run Your Application

After successfully running your application, output of your application should be like the screen below:

Image 8

  1. Click on User Information tab to get the current login user information, it will open a login page to login a user.
    Question: Why will it ask for login?
    Answer: [Authorize] attribute restricts to access data/information for unauthorized requests and redirects to login page to check whether user is valid or not. In our case, we have added this attribute over the UserInformation action method of HomeController.
  2. Register your account before going to login. Click on the Register tab and provide user information as per the below screen:

    Image 9

  3. After successful registration, it will create a cookie in the browser like below:

    Image 10

  4. Now, click on the Login tab and enter username and password like the below screen:

    Image 11

    Click on the UserInformation tab again and now you can find the final result of user information without asking for login.

    Image 12

Summary

In this article, I discussed how to add Identity-Based Authentication in .NET Core 3.0 using In-Memory Database. We have also created a user login and registration forms to login a user to our application to access useful information. I hope this will help readers to understand how to implement the identity-based authentication in any application. Please find the attached code for better understanding.

History

  • 31st January, 2020: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
I am Software Developer Working on .Net Web Technology
ASP.NET MVC,.Net Core,ASP.NET CORE, C#, Angular, React, SQL Server, Windows

Comments and Discussions

 
Questionerror in adding identity Pin
vineyCode17-Oct-21 4:02
vineyCode17-Oct-21 4:02 
QuestionNice (5) Pin
peterkmx2-Feb-20 2:15
professionalpeterkmx2-Feb-20 2:15 
AnswerRe: Nice (5) Pin
Prashant Rewatkar3-Feb-20 4:49
professionalPrashant Rewatkar3-Feb-20 4:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.