Detailed explanation of using Cookie middleware in ASP. NET Core

  • 2021-09-20 19:57:15
  • OfStack

Using Cookie middleware in http://ASP. NET Core

ASP. NET Core provides Cookie middleware to serialize the user subject into an encrypted Cookie and verify this Cookie in a later request, reproduce the user and assign it to the User attribute of the HttpContext object. If you want to provide your own login mode and user data, you can use Cookie middleware to achieve independent functions.

Add and Configure

Step 1 is to add Cookie middleware to your application. Start by adding the Microsoft. AspNetCore. Authentication. Cookies package with nuget. Then add the following lines of code to the Configure method in the Startup. cs file, before app. UseMvc ().


app.UseCookieAuthentication(new CookieAuthenticationOptions()
 {
  AuthenticationScheme = "MyCookieMiddlewareInstance",
  LoginPath = new PathString("/Account/Unauthorized/"),
  AccessDeniedPath = new PathString("/Account/Forbidden/"),
  AutomaticAuthenticate = true,
  AutomaticChallenge = true
 });

The above code snippet configures several options under 1;

Authentication Scheme: This is the value of a given middleware. This option will work when there are multiple instances of middleware if you want to limit authorization to one instance. Login path: This is the relative path to which the program will redirect the request when the user attempts to access the resource without authentication. Disable access path: When a user attempts to access a resource but does not pass any authorization policy for the resource, the request is redirected to this relative path. Automatic authentication: This flag indicates that the middleware should validate on each request and rebuild the serialization principal it created. Automatic challenge: This flag indicates that the browser should be redirected to the login path or the forbidden access path when middleware authentication fails.

Other options include setting the publisher of the claims created by the middleware, the name of the cookie stored by the middleware, the domain of the Cookie, and various security properties on the cookie. By default, the Cookie middleware will use the appropriate security options and set HTTPONLY to prevent cookie from being manipulated by JavaScript on the client side. Restrict the HTTPS operation of Cookie when the request mode is HTTPS.

Create Cookie

To create an Cookie to save your own information, you must initialize an ClaimsPrincipal (type) to serialize and save the user information you want to save to Cookie. Every method call will have a suitable ClaimsPrincipal object in your Controller (controller).


await HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);

The above code will create an encrypted Cookie and add it to the current request response. AuthenticationScheme specifies that during configuration

Quit

Exit the login of the current user, delete the cookie information of the login, and call the following method in the controller.


await HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");

Respond to changes in the back end

Warning

Once cookie is created, it will become the source of identity sheet 1 authentication. Even if the background system is no longer available, the middleware will not know it, and it will always log in until cookie fails.

The Cookie authentication middleware provides 1 series of events in its option class, in which the ValidateAsync () event can be used to interrupt and override the authentication method of cookie authentication.

Considering that the background user's database may have the column 'Last Modified Time', in order to abolish the current Cookie after the database is modified, first, when creating this Cookie, add a declaration of last modified and include the current value, and when the data in the database changes, this value will be updated at the same time.

To implement an ValidateAsync () event override you must write a method with the following signature.


Task ValidateAsync(CookieValidatePrincipalContext context);

http://ASP. NET Core authentication implements this authentication in SecurityStampValidator. Here is a similar example:


public static class LastChangedValidator
 {
  public static async Task ValidateAsync(CookieValidatePrincipalContext context)
  {
   // Pull database from registered DI services.
   var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();
   var userPrincipal = context.Principal;

   // Look for the last changed claim.
   string lastChanged;
   lastChanged = (from c in userPrincipal.Claims
       where c.Type == "LastUpdated"
       select c.Value).FirstOrDefault();

   if (string.IsNullOrEmpty(lastChanged) ||
    !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
   {
    context.RejectPrincipal();
    await context.HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");
   }
  }
 }

These are registered during Cookie middleware configuration


app.UseCookieAuthentication(options =>
 {
  options.Events = new CookieAuthenticationEvents
  {
   // Set other options
   OnValidatePrincipal = LastChangedValidator.ValidateAsync
  };
 });

If you want to update the user principal nondestructively, for example, name is updated, you can call context. ReplacePrincipal () and set context. ShouldRenew to true in a way that does not affect security.

Control Cookie options

The CookieAuthenticationOptions comes with a wide variety of configuration options so you can tune well with the creation of the Cookie.

ClaimsIssuer-Used on top of any middleware-created properties. (Can't understand) CookieDomain-If cookie domain is set to **. http://contoso.com ** then domain names like contoso. com, http://www. contoso. com, staging. contoso. com will also be allowed. CookieHttpOnly-This flag indicates that this cookie will only be accessed by the server. The default value is true. Modifying this property will open your application to Cookie theft and bug for cross-site scripting. CookiePath-This can be used to isolate applications running under the same host. If you have an application running on/app1 and want to restrict the cookie limit to be sent only to yourself, then you should set the CookiePath property to/app1; Cookie will understand that it only applies to Dow/app1 or the request below him. ExpireTimeSpan-Cookie will expire after this TimeSpan period. SlidingExpiration-This flag indicates that Cookie will be reset if accessed after 1.5% of the expiration time. The new expiration time will be moved back to the current time plus ExpireTimespan. The absolute expiration time can be set by ** AuthenticationProperties ** when calling SignInAsync. Absolute expiration improves application security by limiting the time it takes to validate the cookie.

Persistent Cookie and Absolute Expiration Time

You may want to expire cookie through a browser session. Perhaps you also want to end cookie with absolute expiration time and authentication, then you can use the AuthenticationProperties parameter class in HttpContext. Authentication. SignInAsync method when logging in for authentication and creating Cookie. The AuthenticationProperties class is in the Microsoft. AspNetCore. Http. Authentication namespace.

For example


await HttpContext.Authentication.SignInAsync(
  "MyCookieMiddlewareInstance",
  principal,
  new AuthenticationProperties
  {
   IsPersistent = true
  });

This code snippet will create an authentication and corresponding Cookie to enable the browser to close immediately and Cookie will remain. Any expiration time setting in the cookie property will be saved. If Cookie expires when the browser is closed, Cookie will not be cleaned when the browser is restarted.


await HttpContext.Authentication.SignInAsync(
  "MyCookieMiddlewareInstance",
  principal,
  new AuthenticationProperties
  {
   ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
  });

This code will create an authentication and the corresponding cookie and will last for 20 minutes. Any dynamic options configured in Cookie options are ignored. The attributes ExpiresUtc and IsPersistent are independent of each other.

In fact, there are so many bb above, which are useless! Why don't you have an demo


// 1.  In Startup.cs Adj. Configure Add to the method 
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
 AuthenticationScheme = "UserAuth",    // Cookie  Validation scheme name, writing cookie Will be used when. 
 AutomaticAuthenticate = true,                 //  Whether authentication is automatically enabled, if it is not enabled, even if the customer service terminal transmits it Cookie Information, the server will not actively analyze. In addition to explicitly configuring  [Authorize(ActiveAuthenticationSchemes = " Scenario name above ")]  Property will be resolved, this function 1 General use in need of the same 1 When multiple authentication schemes are enabled in an application. Such as points Area.
 LoginPath = "/User/Index"                       //  Login page 
});

// 2.  New UserController
// 3.  Create 1 Test login method (here for the convenience of testing is what I use is get Method to facilitate parameter transfer requests) 
public IActionResult Login(int userId, string userName)
{
 WriteUser(userId, userName);
 return Content("Write");
}

private async void WriteUser(int userId, string userName)
{
 var identity = new ClaimsIdentity("Forms");  //  Specify the authentication type 
 identity.AddClaim(new Claim(ClaimTypes.Sid, userId.ToString()));        //  Users Id
 identity.AddClaim(new Claim(ClaimTypes.Name, userName));                             //  User name 
 var principal = new ClaimsPrincipal(identity);
 await HttpContext.Authentication.SignInAsync("UserAuth", principal, new AuthenticationProperties { IsPersistent = true , ExpiresUtc = DateTime.UtcNow.AddMinutes(20) }); // Expired time 20 Minutes 
}

// 4.  Create 1 Methods to log out of login 
public async Task<ActionResult> Logout()
{
 await HttpContext.Authentication.SignOutAsync("UserAuth"); // Startup.cs The authentication scheme name configured in the 
 return RedirectToAction("User", "Index");
}

// 5.  Create 1 Acquisition cookie The method of user information is convenient to call 
private int GetUserId()
{ 
 //var userName = User.Identity.Name; // Gets the user name stored at logon time 
 var userId = User.FindFirst(ClaimTypes.Sid).Value; //  Object stored at login time Id
 if (string.IsNullOrEmpty(userId))
 {
  return 0;
 }
 else
 {
  return int.Parse(userId);
 }
}
//  Or write 1 Test Action
public JsonResult CheckLogin()
{
 var userName = User.Identity.Name; // Gets the user name stored at logon time 
 var userId = User.FindFirst(ClaimTypes.Sid).Value; //  Object stored at login time Id
 return Json({UserId:userId,UserName:userName});
}

// 6.  The above is the encryption method. If you write it directly, it seems that it is ok 
HttpContext.Response.Cookies.Append("Key", "Value");


Related articles: