Serving Industries Worldwide

Innovative Ways - Satisfied Clientele

Authentication using cookie for frontend application in ASP.NET Core web API


Listening is fun too.

Straighten your back and cherish with coffee - PLAY !

 
 

frontendapplicationinASP.NETCorewebAPI

In earlier days, there was no separation between the front end and back end, and these applications were treated as one. The authentication and authorization in web API can be done using cookies in the same way for a normal web application. The main advantage of using the cookie is to set it up easier than the JWT token.

To secure web apps cookie-based authentication is the most popular choice.

Table of Content

Cookie Options

The cookie option is used to tell the authentication middleware how the cookie behaves in the browser. There are many options available but let's focus on options that affect security the most.

HttpOnly: When HttpOnly is set then the cookie is only available to servers. The browser is used to send cookies but can not access this cookie through javascript.

SecurePolicy: Using SecurePolicy cookie is limited to HTTPS and set this cookie in production is always recommend. For Local set to None.

SameSite: SameSite option is used to indicate whether the browser can use the cookie with cross-site requests. Set this option to LAX while using OAUTH authentication. The strict option is used when Auth cookie is only for a single site. None option will not set the cookie header value

Server Configuration

For server configuration, ASP.Net middleware is used and set up CORS, so that web API accept request from the hosted client.

To set up cookie middleware authentication middleware is used. To set up authentication middleware startup.cs file is used.

Startup.cs file

public void ConfigureServices(IServiceCollection services)
{
    //...
  //other configuration 
    services.AddAuthentication(options => { 
        options.DefaultScheme = "Cookies"; 
    }).AddCookie("Cookies", options => {
        options.Cookie.Name = "Cookie_Name";
        options.Cookie.SameSite = SameSiteMode.None;
        options.Events = new CookieAuthenticationEvents
        {                          
            OnRedirectToLogin = redirectContext =>
            {
                redirectContext.HttpContext.Response.StatusCode = 401;
                return Task.CompletedTask;
            }
        };                
    });

Cookie authentication Scheme can be injected using the AddAuthentication method of IServiceCollection configuration. For defining cookie AddCookie method is used.

Cookie.Name parameter is used to define the name of the cookie.

Same-site is used to control the same name attribute in the set-cookie header and also used to set the cookie. Value of same-site can be strict or lax.

Strict value is used when the request is originated from the domain of the cookie and then the cookie is set to browser otherwise cookie is not sent.

   

Defining CROS Policies

CROS needs to allow from the backend while handling CROS. Request from frontend-only defines what data need from the backend whereas the security is determined by our backend policies.

CROS policy can be configured using backend or server configs. From both way user can configure only one because configuration can both side create issue.

services.AddCors(options =>  
  options.AddPolicy("Development", builder =>  
  {  
    // Allow multiple HTTP methods  
    builder.WithMethods("GET", "POST", "PATCH", "DELETE", "OPTIONS")  
      .WithHeaders(  
        HeaderNames.Accept,  
        HeaderNames.ContentType,  
        HeaderNames.Authorization)  
      .AllowCredentials()  
      .SetIsOriginAllowed(origin =>  
      {  
        if (string.IsNullOrWhiteSpace(origin)) return false;  
        if (origin.ToLower().StartsWith("http://localhost")) return true;  
       return false;  
      });  
  })  
);  

The policy builder allows us to add different HTTP request methods, Accept, Content type, and Authorization Header. Allow credentials are used to pass cookies successfully. For allowing credentials we need to allow origins. Call CORS policies using IApplicationBuilder.

//Allows CROS policies we defined 
App.UseCors(“Development”);]

Securing the cookie configuration

HTTP only cookie option is used to secure cookie and used to protect the cookie from retrieve from malicious XSS script. To secure cookies from unwanted use then the security policy is used for modern browsers.

// Tells the application to transmit the cookie through HTTPS only.  
app.UseCookiePolicy(  
    new CookiePolicyOptions  
    {  
        Secure = CookieSecurePolicy.Always  
    });  

These secure policies accept a cookie only from HTTPS requests and are forc ed when the Same-site option is set to None. Suggestion for local environment comment on both Same-site and Secure policy.

Use the cookie Authentication Middleware

UseAuthentication and UseAuthorization method from IApplicationBuilder is used to make development process more seamless.

// Use this method for Authorization of cookie
app.UseAuthentication();  
app.UseAuthorization();  

Login and Logout Action method in Backend

The Login and Logout methods are the same as the MVC method but won't return any content in response and these methods respond with the appropriate response code.

Login Method

[HttpPost]
public async Task Login(string username, string password)
{
    if (!IsValidUsernameAndPasswod(username, password))
        return BadRequest();
    var users = context.User.Where(x => x.Username == username, ).ToList();
    var claimsIdentity = new ClaimsIdentity(new[]
    {
        new Claim(ClaimTypes.Name, user.Username),
        new Claim(ClaimTypes.Id, user.Id),
    }, "Cookies");
    var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    await Request.HttpContext.SignInAsync("Cookies", claimsPrincipal);

    return NoContent();
}

A cookie is got by calling SignInAsync method of HTTPContext and the cookie is set to the HTTP request. Authorization attribute is used for authorization and that activates UseAuthentication and UseAuthorization Middleware.

Note: “Cookies” is defined in authentication scheme in startup.cs file

 

Searching for Dedicated ASP.Net Core Web Developer ?

Your Search ends here.

 

Logout Method

[HttpPost]
public async Task Logout()
{
    	try
	{
		await HttpContext.SignOutAsync();
    		return OK();
	}
 	catch (Exception ex)  
      	{  
        		return StatusCode(500);  
     	 }  
}

The SignOutAsync method is used to destroy cookies.

The Client (Frontend)

The XMLHttpRequest and FetchAPI are used while consuming the web API that uses cookies using the browser client. You have to set the withCredentials flag to true so that the cookie is not ignored by the browser.

How to set withCredentials flag in different method call with an example:

JQuery

For JQuery you can set withCredentials flag as follow:

$.ajax({
    url: 'http://domain_name/api/account/login?username=theUsername&password=thePassword', 
    method: 'POST', 
    xhrFields: {
        withCredentials: true
    }
});

Angular

For Angular you can set withCredentials flag as follow:

this.httpClient.post(`http://domain_name/api/account/login?username=theUsername&password=thePassword`, {}, {
  withCredentials: true 
}).subscribe( //code )

FetchAPI

For FetchAPI you can set withCredentials flag as follow:

fetch(
'http://domain_name /api/account/login?username=theUsername&password=thePassword', {
    method: 'POST',
    credentials: 'include'
}).then ( //code )

Conclusion

In this blog, we have discussed how to authenticate frontend application using a cookie in web API and also discuss server configuration for that and how to secure cookie and Login and Logout method of the backend for cookie. We learned how to set withcredential attribute for the different front end.

Authentication using cookie for frontend application in ASP.NET Core web API

frontendapplicationinASP.NETCorewebAPI

In earlier days, there was no separation between the front end and back end, and these applications were treated as one. The authentication and authorization in web API can be done using cookies in the same way for a normal web application. The main advantage of using the cookie is to set it up easier than the JWT token.

To secure web apps cookie-based authentication is the most popular choice.

Table of Content

Cookie Options

The cookie option is used to tell the authentication middleware how the cookie behaves in the browser. There are many options available but let's focus on options that affect security the most.

HttpOnly: When HttpOnly is set then the cookie is only available to servers. The browser is used to send cookies but can not access this cookie through javascript.

SecurePolicy: Using SecurePolicy cookie is limited to HTTPS and set this cookie in production is always recommend. For Local set to None.

SameSite: SameSite option is used to indicate whether the browser can use the cookie with cross-site requests. Set this option to LAX while using OAUTH authentication. The strict option is used when Auth cookie is only for a single site. None option will not set the cookie header value

Server Configuration

For server configuration, ASP.Net middleware is used and set up CORS, so that web API accept request from the hosted client.

To set up cookie middleware authentication middleware is used. To set up authentication middleware startup.cs file is used.

Startup.cs file

public void ConfigureServices(IServiceCollection services)
{
    //...
  //other configuration 
    services.AddAuthentication(options => { 
        options.DefaultScheme = "Cookies"; 
    }).AddCookie("Cookies", options => {
        options.Cookie.Name = "Cookie_Name";
        options.Cookie.SameSite = SameSiteMode.None;
        options.Events = new CookieAuthenticationEvents
        {                          
            OnRedirectToLogin = redirectContext =>
            {
                redirectContext.HttpContext.Response.StatusCode = 401;
                return Task.CompletedTask;
            }
        };                
    });

Cookie authentication Scheme can be injected using the AddAuthentication method of IServiceCollection configuration. For defining cookie AddCookie method is used.

Cookie.Name parameter is used to define the name of the cookie.

Same-site is used to control the same name attribute in the set-cookie header and also used to set the cookie. Value of same-site can be strict or lax.

Strict value is used when the request is originated from the domain of the cookie and then the cookie is set to browser otherwise cookie is not sent.

   

Defining CROS Policies

CROS needs to allow from the backend while handling CROS. Request from frontend-only defines what data need from the backend whereas the security is determined by our backend policies.

CROS policy can be configured using backend or server configs. From both way user can configure only one because configuration can both side create issue.

services.AddCors(options =>  
  options.AddPolicy("Development", builder =>  
  {  
    // Allow multiple HTTP methods  
    builder.WithMethods("GET", "POST", "PATCH", "DELETE", "OPTIONS")  
      .WithHeaders(  
        HeaderNames.Accept,  
        HeaderNames.ContentType,  
        HeaderNames.Authorization)  
      .AllowCredentials()  
      .SetIsOriginAllowed(origin =>  
      {  
        if (string.IsNullOrWhiteSpace(origin)) return false;  
        if (origin.ToLower().StartsWith("http://localhost")) return true;  
       return false;  
      });  
  })  
);  

The policy builder allows us to add different HTTP request methods, Accept, Content type, and Authorization Header. Allow credentials are used to pass cookies successfully. For allowing credentials we need to allow origins. Call CORS policies using IApplicationBuilder.

//Allows CROS policies we defined 
App.UseCors(“Development”);]

Securing the cookie configuration

HTTP only cookie option is used to secure cookie and used to protect the cookie from retrieve from malicious XSS script. To secure cookies from unwanted use then the security policy is used for modern browsers.

// Tells the application to transmit the cookie through HTTPS only.  
app.UseCookiePolicy(  
    new CookiePolicyOptions  
    {  
        Secure = CookieSecurePolicy.Always  
    });  

These secure policies accept a cookie only from HTTPS requests and are forc ed when the Same-site option is set to None. Suggestion for local environment comment on both Same-site and Secure policy.

Use the cookie Authentication Middleware

UseAuthentication and UseAuthorization method from IApplicationBuilder is used to make development process more seamless.

// Use this method for Authorization of cookie
app.UseAuthentication();  
app.UseAuthorization();  

Login and Logout Action method in Backend

The Login and Logout methods are the same as the MVC method but won't return any content in response and these methods respond with the appropriate response code.

Login Method

[HttpPost]
public async Task Login(string username, string password)
{
    if (!IsValidUsernameAndPasswod(username, password))
        return BadRequest();
    var users = context.User.Where(x => x.Username == username, ).ToList();
    var claimsIdentity = new ClaimsIdentity(new[]
    {
        new Claim(ClaimTypes.Name, user.Username),
        new Claim(ClaimTypes.Id, user.Id),
    }, "Cookies");
    var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    await Request.HttpContext.SignInAsync("Cookies", claimsPrincipal);

    return NoContent();
}

A cookie is got by calling SignInAsync method of HTTPContext and the cookie is set to the HTTP request. Authorization attribute is used for authorization and that activates UseAuthentication and UseAuthorization Middleware.

Note: “Cookies” is defined in authentication scheme in startup.cs file

 

Searching for Dedicated ASP.Net Core Web Developer ?

Your Search ends here.

 

Logout Method

[HttpPost]
public async Task Logout()
{
    	try
	{
		await HttpContext.SignOutAsync();
    		return OK();
	}
 	catch (Exception ex)  
      	{  
        		return StatusCode(500);  
     	 }  
}

The SignOutAsync method is used to destroy cookies.

The Client (Frontend)

The XMLHttpRequest and FetchAPI are used while consuming the web API that uses cookies using the browser client. You have to set the withCredentials flag to true so that the cookie is not ignored by the browser.

How to set withCredentials flag in different method call with an example:

JQuery

For JQuery you can set withCredentials flag as follow:

$.ajax({
    url: 'http://domain_name/api/account/login?username=theUsername&password=thePassword', 
    method: 'POST', 
    xhrFields: {
        withCredentials: true
    }
});

Angular

For Angular you can set withCredentials flag as follow:

this.httpClient.post(`http://domain_name/api/account/login?username=theUsername&password=thePassword`, {}, {
  withCredentials: true 
}).subscribe( //code )

FetchAPI

For FetchAPI you can set withCredentials flag as follow:

fetch(
'http://domain_name /api/account/login?username=theUsername&password=thePassword', {
    method: 'POST',
    credentials: 'include'
}).then ( //code )

Conclusion

In this blog, we have discussed how to authenticate frontend application using a cookie in web API and also discuss server configuration for that and how to secure cookie and Login and Logout method of the backend for cookie. We learned how to set withcredential attribute for the different front end.