Cookie Authentication

Simple Cookie Authentication in ASP.NET Core 2.x

Authentication plays an essential role in website security. ASP.NET Core provides various ways to authenticate a web application. In this article, we will see simple cookie authentication and how to implement it to the web application.

First, find the ConfigureServices method in the Startup.cs file and add the following code in the ConfigureServices method just before services. AddMvc() method to create authentication middleware services. Also, include  Microsoft.AspNetCore.Authentication.Cookies Package.

public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options => { options.LoginPath = “/Login”; });
services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.AuthorizeFolder(“/”);
    options.Conventions.AllowAnonymousToPage(“/Login”);
});
services.AddMvc();
}

In the above code, CookieAuthenticationDefaults.AuthenticationScheme is passed to AddAuthentication() to set the default authentication scheme. Then AddCookie() method configures the authentication. This method has LoginPath option. It will redirect to the login page when the user attempts to access the page, which requires authentication. Also, it will append the requested page’s URL to the login URL.

For example, the following is a URL to access the Index page but it requires authentication. https://www.example.com/Index

When the user enters the URL in the browser address box, it will redirect to the Login page with the ReturnUrl query string. The ReturnUrl will point to the user requested Index page. The below is an example of a Login page URL which has been redirected by the authentication process. https://www.example.com/Login?ReturnUrl=%2FIndex

Once the login provides the sign-in identity, the browser redirects to the requested page.

AddRazorPagesOptions helps to control the access of the razor pages. From the above code, the AuthorizeFolder convention will add the authorize filter to the pages under the specific folder. Here AuthorizeFolder passes the root folder path(“/”) so it will add the authorize filter to all the page. And AllowAnonymousToPage convention passes the Login page path(“/Login”) parameter. So anyone can access the login page, it does not require any authentication.

Add app.UseAuthentication() method before app.UseMvc() method in the Configure() method. This will add authentication capabilities to the application.

public void  Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMvc();
}

The following is a razor page to get the credential information from the user. It has asp-validation-summary to display a summary of the validation message.

@page
@model RazorPageWebApplication.Pages.LoginModel
@{
ViewData[“Title”] =  “Login”;
}
 
<h2>Account Login </h2>
 
<html>
<body>
<form  method=”post”>
<div asp-validation-summary =”All  class=”text-danger”></div >
Username: <input  asp-for=”loginData.Username  placeholder=”Username”  class=”form-control”  /><br />
Password: <input  asp-for=”loginData.Password  placeholder=”Password”  class=”form-control”  /><br />
Remember me: <input  asp-for=” loginData.RememberMe />< br />
<input  type=”submit” value =”Login” class =”btn btn-primary” />
</form >
</body>
</html>

Below code is the PageModel code.  Here [BindProperty] attribute is added in LoginData class. So that the ASP.NET model binding will bind the properties with the HTTP request. For more info about model binding check this Model Binding in ASP.NET Core article. Here, the username and password are checked to ensure whether the user is registered or not.

Note:

For example purpose, the username and password are hard-coded with the common user name admin and password as the password. But in the real application, get the credentials from the database and check with the username and password.

ClaimsPrincipal has been used to hold the cookie information. In the following code, the claim list stores Name Identifier and Name. Then, SignInAsync method signs the specified user. After the login, the application will redirect to the Index page

using System.ComponentModel.DataAnnotations;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
 
    public  class LoginModel  : PageModel
    {
        [BindProperty]
        public LoginData loginData {  getset ; }
 
        public  async Task<IActionResult> OnPostAsync()
        {
            if (ModelState.IsValid)
            {
                var isValid = (loginData.Username ==  “admin” && loginData.Password == “password” );
                if (!isValid)
                {
                    ModelState.AddModelError(“” Username or  Password is invalid”);
                    return  Page();
                }
 
                var claimsIdentity =  new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
                claimsIdentity.AddClaim(new  Claim(ClaimTypes.NameIdentifier, loginData.Username));
                claimsIdentity.AddClaim(new  Claim(ClaimTypes.Name, loginData.Username));
 
                ClaimsPrincipal principal = new  ClaimsPrincipal(claimsIdentity);
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal,  new AuthenticationProperties { IsPersistent = loginData.RememberMe });
                return RedirectToPage( “Index”);
            }
            else
            {
                ModelState.AddModelError(“” “Username or password is blank”);
                return Page();
            }
        }
 
        public  class LoginData
        {
            [Required]
            public  string Username { get set; }
 
            [Required, DataType(DataType.Password)]
            public  string Password { get set; }
 
            public  bool RememberMe { get set; }
        }
    }

SignOutAsync() helps to sign out the application. It will sign out the applicant and also clear the cookies.

await HttpContext.SignOutAsync( CookieAuthenticationDefaults.AuthenticationScheme);

This article explains simple cookie authentication without identity. If you have any comments, leave it in the comment text box below.

Leave a Reply

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