Simple Cookie Authentication in ASP.NET Core

Authentication is the process of verifying that the user has access to the application. There are several ways to achieve this in ASP.NET Core. This blog is going to explain how to implement it on ASP.NET Core MVC.

Gradually, we will see how to implement it

Step 1:
First, you need to add AddAuthentication to ConfigureServices. That registers the services required for authentication services. The following code registers the cookie authentication services.

Startup.cs
public void ConfigureServices(IServiceCollection services)
{
   ...
   ...
   ...
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.Cookie.Name = "SampleCookieAuth";
            options.LoginPath = "/Account/Login";
        });

    services.AddControllersWithViews();
}

Next, you have to add the UseAuthentication extension method above the UseAuthorization method. It adds authentication middleware.

Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
   ...
   ...
   ...

    app.UseAuthentication();
    app.UseAuthorization();

   ...
   ...
   ...
}

Step 2:
Create a user class to get the username and password. Also, I have added GetUsers() to retrieve the username and password. For example purposes, I have directly initialized it. For real applications, you must fetch it from the database.

Users.cs
public class Users
{ 
    public string Username { get; set; }
    public string Password { get; set; }

    public IEnumerable<Users> GetUsers()
    {
        return new List<Users>() { new Users { Username = "admin", Password = "123" } };
    }
}

Step 3:
This step is a Controller class. The first method is a login() GET method. The second method is a login POST method, this method confirms the user login username and password, sets the claims and logins into the application. Claiming helps keep user information. The final method is a logout method it logout the user from the application.

AccountController.cs
public class AccountController : Controller
{
    [HttpGet]
    public ActionResult Login()
    {
        Users user = new Users();
        return View(user);
    }

    [HttpPost]
    public async Task<ActionResult> Login(Users user)
    {
        var users = new Users();
        if (users.GetUsers().Any(u => u.Username == user.Username && u.Password == user.Password)) // Check DB value
        {
            var userClaims = new List<Claim>()
        {
        new Claim(ClaimTypes.Name, user.Username),
        new Claim(ClaimTypes.Email, "admin@mail.com"),
        };

            var identity = new ClaimsIdentity(userClaims, CookieAuthenticationDefaults.AuthenticationScheme);

            var userPrincipal = new ClaimsPrincipal(new[] { identity });

            await HttpContext.SignInAsync(userPrincipal);

            return RedirectToAction("Index", "Home");
        }

        return View(user);
    }

    [HttpPost]
    public async Task<ActionResult> Logout()
    {
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        return RedirectToAction("Login", new Users());
    }
}

Step 4:
This step is a View page. In this view, I have added two text boxes to collect the username and password and a submit button to submit the form.

Account/Index.cshtml
@model SampleWebApplication.Models.Users
<div class="row">
    <div class="col-md-4">
        <form asp-controller="Account" asp-action="Login">       
            <div class="form-group">
                <label asp-for="Username" class="control-label"></label>
                <input asp-for="Username" class="form-control" />
                <span asp-validation-for="Username" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Password" class="control-label"></label>
                <input type="password" asp-for="Password" class="form-control" />
                <span asp-validation-for="Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Login" class="btn btn-default btn-primary" />
            </div>
        </form>
    </div>
</div>   

The following is a logout view it has a successfully logged message and a logout button

Home/Index.cshtml
<form asp-controller="Account" asp-action="Logout">
    <h4>You have successfully logged in</h4>
    <input type="submit" value="Logout" class="btn btn-primary" />
</form>

Step 5:
This step is HomeController. After logging into the application, you will be redirected to the home controller's index page. In the below code, I have added the [Authorize] attribute above the HomeController. This attribute checks whether the user is logged in or not. Here I have added this attribute at the Controller level. But you can also add it to the action level if you want. Make sure you add all actions method that requires authorization.

HomeController.cs
[Authorize]
public class HomeController : Controller
{        
    public IActionResult Index()
    {
        return View();
    }
}

Output

I hope this helps you. Keep coding.

Comments

Popular posts from this blog

Entity Framework Core (EF) with SQL Server LocalDB

Creating a C# Azure Function with Visual Studio: Step-by-Step Guide

Exploring EventCallback in Blazor: Building Interactive Components