Use Cookies for identity verification

Source: Internet
Author: User
Tags httpcontext send cookies ticket


The article is an official MSDN document, linked here. In fact, there are Chinese documents, here still want to make a record.



The article has ASP. NET core 2.x and 1.x versions, and I'm ignoring 1.x here.



Here are some additional things that can help you understand.


Authentication and Authorization


Let's talk about the difference between the two words of authentication and authorization.



Authentication: Certification.



Authorization: Authorization.



In short, certification is used to prove a person's identity, such as he is a student, a teacher, a boss, then need such a certification. Authorization is used to indicate what the user can do, such as admin can modify delete data, normal user can only view data.


Issuer and audience


Issuer: The issuer, here is the cookie who distributed it.



Audience: Audience, who is the audience for this cookie.


Body


As you can see in the previous certification-related topics, the ASP. NET Core Identity is a complete authentication solution for creating users and maintaining user logins. But sometimes you may also want your own cookie-based authentication method. You can use cookies without using the ASP. NET core identity to implement a separate authentication service.



Sample source code is here.



Because we are just doing a demo program, so write dead a hypothetical user Maria Rodriguez into the system. The user name associated with the mailbox is "maria.rodriguez@contoso.com" and the password is arbitrary. The userPages/Account/Login.cshtml.csauthenticates through the method in the fileAuthenticateUser. The actual environment should be based on the database.



Learn more about how to refer to the information from ASP. 1.x to 2.0 here.



To use the ASP. NET Core Identity, refer to here.


Configuration


If the program does not use the MICROSOFT.ASPNETCORE.APP meta package, give the program a reference to Microsoft.AspNetCore.Authentication.Cookies (version ≥2.1.0).



InConfigureServices, add theAuthenticationauthentication Service through the andAddCookiemethod.


services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)    .AddCookie();


AddAuthenticationthe passedAuthenticationSchemevalue sets the authentication scheme that the program uses by default.



AuthenticationSchemeThis is useful when you have multiple instances of cookie authentication or if your system uses a specific scheme to authenticate. SetCookieAuthenticationDefaults.AuthenticationSchemeto be used as a scheme with ' Cookies '. You can set any string type value to differentiate between different scenarios.



In theConfiguremethod, useUseAuthenticationto invoke the authentication middleware to set theHttpContext.Userproperties. The method should beUseMvcWithDefaultRouteUseMvccalled before the and methodUseAuthentication.


Addcookie setting options


This is roughly the setting:


services
    .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.ClaimsIssuer = "test";
        options.ClaimsIssuer = "aa";
        //and other...
    });


Specific detailsCookieAuthenticationOptionsto set the relevant options. Focus on a few key settings, such as Accessdeniedpath, Loginpath, Logoutpath, Domain, Name,ExpireTimeSpan.


Options Description
Accessdeniedpath WhenHttpContext.ForbidAsyncThe jump address is triggered at 302, the default/Account/AccessDenied
Claimsissuer The Issuer property used to set the cookie.
Cookie.domain The valid domain of the cookie. The default is the requested server name. The browser will only send cookies to the compliant server. You might want to set this value to adjust his scope. For example, set.contoso.comhis scope to includecontoso.com, andwww.contoso.comstaging.www.contoso.comso on.
Cookie.expiration Gets or sets the validity period of the cookie. Core 2.1+ is not recommended for use. The recommendation isExpireTimeSpanto use to set the expiration time of the cookie.
Cookie.httponly Set whether the cookie is accessible only by the server, by default True, can be set to False to the client JS script access, but may cause XSS (cross-site scripting attacks).
Cookie.name The name of the cookie.
Cookie.path Used to isolate different sites under the same server. For example, the site is run/app1below, set this property for/app1, then this cookie is only valid under App1.
Cookie.samesite Indicates whether the browser allows cookies to be attached to the same site. There are several enumerations:SameSiteMode.Strictonly the same site is allowed.SameSiteMode.Laxallows you to attach to a different site or to the same site in a secure HTTP manner. To support OAuth authentication, it needs to be set toSameSiteMode.Lax.
Cookie.securepolicy Sets whether HTTPS is allowed only.
Dataprotectionprovider For setup creationTicketDataFormat(at the end of the table)
Events Set up a handler for some time. For exampleOnSignedIn,OnSigningOutwait, the default is not to do any action.
Eventstype The type of events.
Expiretimespan Sets the expiry time of the authentication ticket stored in the cookie. The service side verifies the validity of the encrypted ticket.IsPersistentIt can also be returned in the Set-cookie head after it has been set. The default expiration time is 14 days.
Loginpath HttpContext.ChallengeAsyncMethod triggers the address of the 302 jump. Assuming/account/loginthat, for example, the current access/securereturns 401, the URL jumps to the address/account/login?returnUrl=/secureand the browser jumps to the secure page when the login page generates a new login identity. The default value is/Account/login
Logoutpath Log out address.
Returnurlparameter Login or log out after the page can do a jump, the jump address as a parameter passed, this is used to set the name of this parameter.
Sessionstore Used to hold identity information for cross-site requests. Once set, only the session identifier is sent to the client. It can be used when the identity is much more.
SlidingExpiration Sliding expires. Identifies whether a new cookie with a new expiration time can be distributed dynamically. Can beSignInAsyncused inside a methodAuthenticationProperties. Use an absolute cookie expiration time to increase the security of your app. As an example:await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTime.UtcNow.AddMinutes(20) });
Ticketdataformat
Validate Verifies whether the current option is valid.
Cookie Policy Middleware


Cookie policy Middleware. Used to set the compatibility of the cookie for the app. is related to the order and only affects the settings behind the program pipeline. Used in the following way.


app.UseCookiePolicy(cookiePolicyOptions);


Cookiepolicyoptions provides settings related to the global nature of the program. And can hook up some handlers when the cookie is added or deleted. Have the following properties.


Properties Description
HttpOnly Sets whether the cookie is accessible only through the server. Default isHttpOnlyPolicy.None
checkconsentneeded A function that returns BOOL if true will pop up a page to let the user confirm the use of the cookie
Consentcookie (This document does not say ...) )
Minimumsamesitepolicy With the site policy, by defaultSameSiteMode.Lax, the ASP. NET core2.0+ is available.
Onappendcookie The cookie is called when it is appended.
Ondeletecookie Called when the cookie is deleted.
Secure Identifies whether the cookie must be https.
Create an authentication cookie


Creating a cookie that contains user information requires constructing a claimsprincipal. User information is serialized and stored in a cookie.



Construct a claimsidentity with the necessary claim, and then call theSignInAsyncmethod.


var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
}
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
//AllowRefresh = <bool>,
// Refreshing the authentication session should be allowed.
//ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
//The absolute expiration time of the cookie will override the setting of the expiretimespan.
//IsPersistent = true,
//Indicates whether the cookie is persistent so that it can be delivered between different requests. Setting expiretimespan or expiresuttc is required.
//IssuedUtc = <DateTimeOffset>,
//Time of certificate authentication.
//RedirectUri = <string>
//The path when HTTP jumps.
}
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);


SignInAsyncMethod creates an encrypted cookie and then adds it to the current response. The default scheme will be used if Authenticationscheme is not set.



Encryption is implemented based on the ASP. NET Core Data protection system, so if the program is deployed on multiple machines or is load balanced, you need to configure data protection (similar to the one in the current year, ASP. )


Log out


SignOutAsyncUsed to log out the current user and delete cookies. The code is as follows.


await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);


Login and logout need to use the same scheme name. The same authenticationscheme.


Respond to changes in the background


When a cookie is created, it becomes the only source of identity. Even if the current user is disabled in the background because the cookie that has been distributed is not known, the user can still remain logged in until the cookie expires.



The Validateprincipal event can be used to intercept or overwrite the authentication of a cookie. This reduces the risk of the system being compromised by the user who is being recalled. This function can be implemented in the following way.



First, modify the Signinasync method to obtain the user-related claim.


var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
New claim ("lastchanged", {database value}) / / add a lastchanged value and record the value
}
var claimsIdentity = new ClaimsIdentity(
Claims,
CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));


Then create aCustomCookieAuthenticationEventsinherit fromCookieAuthenticationEvents


using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
private readonly IUserRepository _userRepository;
public CustomCookieAuthenticationEvents(IUserRepository userRepository)
{
//Get user related information from di
_userRepository = userRepository;
}
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
var userPrincipal = context.Principal;
//Find the claim related to lastchanged above
var lastChanged = (from c in userPrincipal.Claims
where c.Type == "LastChanged"
select c.Value).FirstOrDefault();
if (string.IsNullOrEmpty(lastChanged) ||
! _userrepository. Validatelastchanged (lastchanged)) / / call validatelastchanged to determine whether the amount cookie related to lastchanged is a valid cookie
{
Context. Rejectprincipal(); / / reject this cookie
await context.HttpContext.SignOutAsync(
Cookieauthenticationdefaults. Authenticationscheme); / / automatically log out
}
}
//Other methods can be set
public override Task SignedIn(CookieSignedInContext context)
{
return base.SignedIn(context);
}
}


And then byEventsTypecalling this setting, and then injecting thisCustomCookieAuthenticationEvents


services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.EventsType = typeof(CustomCookieAuthenticationEvents);
    });

services.AddScoped<CustomCookieAuthenticationEvents>();


Consider a situation where if the user does not affect the security of the system after the update, you can consider replacing it with a principal that iscontext.RejectPrincipal()context.ReplacePrincipalsetcontext.ShouldRenew=trueto update the user without compromising.


The implementation of the above will be triggered at each request, so it will have a certain impact on the performance of the system.

Persistent cookie


You may want to persist cookies so that they can be used between different processes in the browser. The persistence of cookies should be done in a similar way to display the "Remember Me" check box on the interface and then let the user click. Other similar mechanisms are also in line.



The following code is used to implement cookie persistence.


await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });


If the cookie expires during browser shutdown, the browser will automatically delete the cookie the next time it starts.



AuthenticationpropertiesMicrosoft.AspNetCore.Authenticationinside the namespace.


Absolute Expiration Time


Can be usedExpiresUtcto set the absolute expiration time, but must be set at the same time, no one thisIsPersistentparameter will be ignored, and this cookie is only the current reply valid.



When set in the Signinasync methodExpiresUtc, it will overwriteCookieAuthenticationOptionsthe setExpireTimeSpan.



The following code sets a persistent cookie with a 20min validity period, and other settings related to the expiration date are ignored.


await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });

At the end of the moment, the MSDN is great.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.