当前位置:网站首页>Understand asp Net core - Cookie based authentication
Understand asp Net core - Cookie based authentication
2022-07-23 10:48:00 【biyusr】
summary
Usually , Identity Authentication (Authentication) And authorization (Authorization) Will be put together . however , Because these two English are similar , And “ Certificate authority ” Four words are often used together , This leads to confusion among some readers who have just come into contact with this knowledge , Can't tell the difference between authentication and authorization , Even think these two are the same . therefore , I want to give you a brief distinction between identity authentication and authorization .
Identity Authentication
Confirm who is performing the operation .
When users request background services , The system first needs to know who the user is , It's Zhang San 、 Li Si is still anonymous ? The process of identifying is “ Identity Authentication ”. In our real life , By showing your ID card , Others can quickly confirm your identity .
to grant authorization
Confirm whether the operator has the authority to perform the operation .
After confirming the identity , Have learned the user information , Then comes the authorization stage . At this stage , What we need to do is to confirm whether the user has permission to perform this operation , For example, confirm whether Zhang San has permission to view products 、 Whether there is editing permission, etc .
Cookie
Cookie For many people , It's a familiar thing , Be familiar with the present Web application , Basically cannot leave it , If you are right about Cookie I don't know much about , Don't panic , I sorted out some high-quality articles for you at the end of the article , Recommended for Cookie After an overall understanding , Then continue to read the content below !
be based on Cookie Authentication , The usual solution is after the user logs in successfully , The server records the necessary information of the user in Cookie in , And send it to the browser , Later, when the user sends a request , The browser will Cookie Send it back to the server , The server can use Cookie The information in confirms the user information .
Before we start , In order to facilitate everyone to understand and operate , I have prepared a sample program , Please visit XXTk.Auth.Samples.Cookies.Web Access to the source code . The code in the article , Basically, it is implemented in the sample program , It is strongly recommended to eat in combination !
Identity Authentication (Authentication)
Add identity authentication middleware
stay ASP.NET Core in , For authentication , Need to be in HTTP Request the pipeline to pass UseAuthentication Add identity authentication middleware ——AuthenticationMiddleware:
csharp
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
// Authentication middleware
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
UseAuthenticationIt must be placed inUseEndpointsBefore , otherwiseControllerCan't go throughHttpContextGet identity information .
AuthenticationMiddleware It's a simple thing to do , Is to confirm the user's identity , At the code level, it is to HttpContext.User assignment , Please refer to the code below :
csharp
public class AuthenticationMiddleware
{
private readonly RequestDelegate _next;
public AuthenticationMiddleware(RequestDelegate next, IAuthenticationSchemeProvider schemes)
{
_next = next;
Schemes = schemes;
}
public IAuthenticationSchemeProvider Schemes { get; set; }
public async Task Invoke(HttpContext context)
{
// Record the original path and the original base path
context.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
{
OriginalPath = context.Request.Path,
OriginalPathBase = context.Request.PathBase
});
// If there is an explicit identity authentication scheme , priority ( Don't look here , Look straight down )
var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
{
var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;
if (handler != null && await handler.HandleRequestAsync())
{
return;
}
}
// Use the default identity authentication scheme for authentication , And the assignment HttpContext.User
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
if (defaultAuthenticate != null)
{
var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
if (result?.Principal != null)
{
context.User = result.Principal;
}
}
await _next(context);
}
}
To configure Cookie Certification scheme
Now? , Authentication middleware has been added , Now you need to ConfigureServices Method to add the services needed for identity authentication and configure the authentication scheme .
We can go through AddAuthentication Extend the method to add services required for identity authentication , And optionally specify the name of the default authentication scheme , The following is an example :
csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
We added the services that identity authentication depends on , And specified a name CookieAuthenticationDefaults.AuthenticationScheme Default authentication scheme for , namely Cookies. Obviously , It is based on Cookie Identity authentication scheme .
CookieAuthenticationDefaults Is a static class , Defines some common default values :
csharp
public static class CookieAuthenticationDefaults
{
// Certification scheme name
public const string AuthenticationScheme = "Cookies";
// Cookie The prefix of the name
public static readonly string CookiePrefix = ".AspNetCore.";
// Login path
public static readonly PathString LoginPath = new PathString("/Account/Login");
// Logout path
public static readonly PathString LogoutPath = new PathString("/Account/Logout");
// Access denied path
public static readonly PathString AccessDeniedPath = new PathString("/Account/AccessDenied");
// return url Parameter name of
public static readonly string ReturnUrlParameter = "ReturnUrl";
}
Now? , We have specified the default authentication scheme , The next step is to configure the details of this scheme , Through the heel AddCookie To achieve :
csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
// Here is the detailed configuration of the scheme
});
}
}
Obviously ,AddCookie The first parameter of is to specify the name of the authentication scheme , The second parameter is detailed configuration .
adopt options, You can login 、 Cancellation 、Cookie And so on . Its type is CookieAuthenticationOptions, Inherited from AuthenticationSchemeOptions. There are many properties , I will choose some commonly used ones to explain .
in addition , Because when configuring options , Need to rely on DI Services in containers , Therefore, we have to change the configuration of options from AddCookie Proposed in the extension method .
Please check the following code :
csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme)
.Configure<IDataProtectionProvider>((options, dp) =>
{
options.LoginPath = new PathString("/Account/Login");
options.LogoutPath = new PathString("/Account/Logout");
options.AccessDeniedPath = new PathString("/Account/AccessDenied");
options.ReturnUrlParameter = "returnUrl";
options.ExpireTimeSpan = TimeSpan.FromDays(14);
//options.Cookie.Expiration = TimeSpan.FromMinutes(30);
//options.Cookie.MaxAge = TimeSpan.FromDays(14);
options.SlidingExpiration = true;
options.Cookie.Name = "auth";
//options.Cookie.Domain = ".xxx.cn";
options.Cookie.Path = "/";
options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.IsEssential = true;
options.CookieManager = new ChunkingCookieManager();
options.DataProtectionProvider ??= dp;
var dataProtector = options.DataProtectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", CookieAuthenticationDefaults.AuthenticationScheme, "v2");
options.TicketDataFormat = new TicketDataFormat(dataProtector);
options.Events.OnSigningIn = context =>
{
Console.WriteLine($"{context.Principal.Identity.Name} Logging in ...");
return Task.CompletedTask;
};
options.Events.OnSignedIn = context =>
{
Console.WriteLine($"{context.Principal.Identity.Name} Logged in ");
return Task.CompletedTask;
};
options.Events.OnSigningOut = context =>
{
Console.WriteLine($"{context.HttpContext.User.Identity.Name} Cancellation ");
return Task.CompletedTask;
};
options.Events.OnValidatePrincipal += context =>
{
Console.WriteLine($"{context.Principal.Identity.Name} verification Principal");
return Task.CompletedTask;
};
});
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
The above configuration , Most of them use the default value of the program , Next, we will explain in detail one by one :
LoginPath: Login page path , Point to oneAction.Default
/Account/Login.When the server does not allow anonymous access and needs to confirm user information , Jump to this page to log in .
in addition , Login methods usually have a parameter , called
return url, Used when the user logs in successfully , Automatically jump back to the previously visited page . This parameter will also be automatically passed to theAction, It will be explained in detail below .
LogoutPath: Logout path , Point to oneAction. Default/Account/Logout.AccessDeniedPath: Access denied page path , Point to oneAction. Default/Account/AccessDenied. When there is a Http Status code 403 when , Will jump to this page .ReturnUrlParameter: As mentioned abovereturn urlParameter name of , The parameter value will be passed through query Is passed to this parameter . DefaultReturnUrl.ExpireTimeSpan: Certification paper (authentication ticket) The validity of the .Default 14 God
In the code, the authentication ticket is of type
AuthenticationTicketThe object of , It's like a handbag , It's full of items that can prove your identity , Such as ID card 、 Driver's license, etc .Authentication tickets are stored in Cookie in , Its validity period and location Cookie The validity period of is independent , If Cookie No expired , But the certificate has expired , Can't pass the certification . When explaining the login section below , There is a detailed description of the validity period of the certified bill .
Cookie.Expiration:Cookie The expiration time of , That is, the saving time in the browser , For persistence Cookie.Corresponding Cookie Medium
Expiresattribute , Is a definite point in time .Currently disabled , We cannot assign a value to it .
Cookie.MaxAge:Cookie The expiration time of , That is, the saving time in the browser , For persistence Cookie.Corresponding Cookie Medium
Max-Ageattribute , It's a time frame .If Cookie Of
Max-AgeandExpiresSimultaneous setting , withMax-AgeSubject toIf not set Cookie Of
Expires, meanwhileCookie.MaxAgeKeep the value ofnull, Then the Cookie The validity period of is the current session (Session), When the browser is closed ,Cookie Will be cleared ( actually , Now some browsers have session recovery function , Close the browser and reopen ,Cookie Will also follow the recovery , As if the browser had never been closed ).
SlidingExpiration: instructions Cookie Whether the expiration method of is sliding expiration . Defaulttrue. In case of sliding expiration , After the server receives the request , If you find that Cookie The survival time of has exceeded half , Then the server will reissue a new Cookie,Cookie Both the expiration time of and the expiration time of the authentication ticket will be reset .Cookie.Name: The Cookie Name , The default is.AspNetCore.Cookies.Cookie.Domain: The Cookie Domain , Corresponding Cookie OfDomainattribute . General with “.” start , allow subdomain All accessible . The default is request Url The domain of .Cookie.Path: The Cookie The path , Corresponding Cookie OfPathattribute . Default/.Cookie.SameSite: Set whether to carry when sending requests across sites through the browser Cookie The pattern of , There are three kinds , NamelyNone、LaxandStrict.csharp
public enum SameSiteMode { Unspecified = -1, None, Lax, Strict }SameSiteMode.Unspecified: Use the browser's default mode .SameSiteMode.None: No restrictions , When sending the same site or cross site request through the browser , They all carry Cookie. This is a very deprecated model , Be vulnerable toCSRF attackSameSiteMode.Lax: The default value is . Send the same site request or cross site part through the browser GET When asked , Can carry Cookie.SameSiteMode.Strict: Only when sending the same site request through the browser , Will carry Cookie.More specific content , Refer to the good article recommendation at the bottom
Cookie.HttpOnly: Indicates that the Cookie Can it be used by client script ( Such as js) visit . The default istrue, That is, prohibit client script access , This can effectively preventXSS attack.Cookie.SecurePolicy: Set up Cookie Security policy , Corresponding to Cookie OfSecureattribute .csharp
public enum CookieSecurePolicy { SameAsRequest, Always, None }CookieSecurePolicy.Always: Set upSecure=true, When sending login request and subsequent request are Https when , Browsers will Cookie Send it to the server .CookieSecurePolicy.None: Not set upSecure, Send Http Request and Https When asked , Browsers will Cookie Send it to the server .CookieSecurePolicy.SameAsRequest: The default value is . As the case may be , If the login interface is Https request , Is setSecure=true, otherwise , Not set up .
Cookie.IsEssential: Indicates that the Cookie It is necessary for the normal operation of the application , It does not need to be used with the consent of the userCookieManager:Cookie Manager , Used to add a response Cookie、 Query request Cookie Or delete Cookie. The default isChunkingCookieManager.DataProtectionProvider: Authentication ticket encryption and decryption provider , Corresponding encryption and decryption tools can be provided on demand . The default isKeyRingBasedDataProtector. Knowledge about data protection , Please refer to the official documentation -ASP.NET Core Data protection .TicketDataFormat: The data format of the authentication ticket , Through internalDataProtectionProviderThe provided encryption and decryption tool encrypts and decrypts authentication tickets . The default isTicketDataFormat.
Here are some event callbacks :
Events.OnSigningIn: Callback before loginEvents.OnSignedIn: Callback after loginEvents.OnSigningOut: Callback when logging outEvents.OnValidatePrincipal: verification Principal Time callback
If you think it's not elegant to register callback like this , Then you can inherit from CookieAuthenticationEvents To implement their own classes , Rewrite the corresponding method internally , Such as :
csharp
public class MyCookieAuthenticationEvents : CookieAuthenticationEvents {}
Last , stay options Replace at :options.EventsType = typeof(MyCookieAuthenticationEvents);
Cross domain (Cross Origin): Requested Url With the current page Url Contrast , agreement 、 domain name 、 Any one of the port numbers is different , It is regarded as cross domain .
cross-site (Cross Site): Cross station is relative to cross domain , Loose rules , Requested Url With the current page Url Contrast ,eTLD + 1 Different , It is regarded as cross station .
Please refer to Understanding "same-site" and "same-origin"
User login and logout
The user login
Now? , Finally, it's time for users to log in and log out . Do you remember? , Login configured in the scheme 、 Cancellation 、 The forbidden access path should correspond to the interface .
ASP.NET Core For login , Provides HttpContext Extension method of SignInAsync, We can use it to login . Only Controller Code for , For front-end code, please refer to github Source code .
csharp
public class AccountController : Controller
{
[HttpGet]
public IActionResult Login([FromQuery] string returnUrl = null)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
[HttpPost]
public async Task<IActionResult> Login([FromForm] LoginViewModel input)
{
ViewBag.ReturnUrl = input.ReturnUrl;
// If the user name and password are the same, the login is considered successful
if (input.UserName != input.Password)
{
ModelState.AddModelError("UserNameOrPasswordError", " Invalid user name or password ");
}
if (!ModelState.IsValid)
{
return View();
}
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
identity.AddClaims(new[]
{
new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString("N")),
new Claim(ClaimTypes.Name, input.UserName)
});
var principal = new ClaimsPrincipal(identity);
// Sign in
var properties = new AuthenticationProperties
{
IsPersistent = input.RememberMe,
ExpiresUtc = DateTimeOffset.UtcNow.AddSeconds(60),
AllowRefresh = true
};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, properties);
if (Url.IsLocalUrl(input.ReturnUrl))
{
return Redirect(input.ReturnUrl);
}
return Redirect("/");
}
}
First of all Claim、Identity and Principal:
Claim: A statement that represents a message . Take our ID card as an example , It contains the name 、 Gender and other information , Such as “ full name : Zhang San ”、“ Gender : male ”, These are all Claim.Identity: Indicates an identity . For oneClaimsIdentityCome on , It is composed of one or more Claim Composed of . Our ID card is a Identity.Principal: Represents the user himself . For oneClaimsPrincipalCome on , It is composed of one or more ClaimsIdentity Composed of . Think about it , Each of us has more than one identity , In addition to the ID card , And a driver's license 、 Membership cards, etc .
go back to Login Method , First of all, a statement of ClaimsIdentity example , And will CookieAuthenticationDefaults.AuthenticationScheme Pass in as an authentication type . It should be noted that , This certification type must not be null Or empty string , otherwise , Under default configuration , You get the following error :
pgsql
InvalidOperationException: SignInAsync when principal.Identity.IsAuthenticated is false is not allowed when AuthenticationOptions.RequireAuthenticatedSignIn is true.
And then , We regard some non sensitive information of users as Claim It's deposited in ClaimsIdentity in , And finally put it into ClaimsPrincipal example .
stay SignInAsync In the extension method , We can configure the authentication , adopt AuthenticationProperties.
IsPersistent: Whether the bill is persistent , That is, where the bill is located Cookie Persistent or not . If you persist , Will be belowExpiresUtcIs set to Cookie OfExpiresattribute . The default isfalse.ExpiresUtc: The expiry date of the bill , The default isnull, Ifnull, beCookieAuthenticationHandlerWill be inHandleSignInAsyncmethod Cookie In the authentication scheme configurationCookieAuthenticationOptions.ExpireTimeSpan+AuthenticationProperties.IssuedUtcThe result of is assigned to this attribute .AllowRefresh: As mentioned above , stay Cookie Authentication scheme configuration of , The expiration method can be configured as sliding expiration , When conditions are met , Will be reissued Cookie. actually , To achieve this effect , Try to makeAllowRefreshSet tonullperhapstrueCan only be . The default isnull.IssuedUtc: Time of issue , The default isnull. Generally, there is no need to assign values manually , bynullwhen ,CookieAuthenticationHandlerWill be inHandleSignInAsyncMethod to assign the current time to this attribute .
Here is a detailed description of the validity period of the certified bill :
We have learned from the above , The validity period of the certified bill is through AuthenticationProperties.ExpiresUtc To set up , It is a definite point in time , If we don't assign this attribute manually , that Cookie Authentication processor CookieAuthenticationHandler Will Cookie In the authentication scheme configuration CookieAuthenticationOptions.ExpireTimeSpan + AuthenticationProperties.IssuedUtc The result of is assigned to this attribute .
And we know , In the configuration Cookie Certification scheme ,Cookie.Expiration Property represents Cookie Of Expires attribute , But it is disabled , If you force it , We will get such an option verification error message :
text
Cookie.Expiration is ignored, use ExpireTimeSpan instead.
But ExpireTimeSpan attribute , The note clearly states that it does not refer to Cookie Of Expires attribute , It's the validity of the bill , What's going on ? Actually , You can imagine the following scenario : The Cookie Of Expires and Max-Age Are not set ( The program allows them to be empty ), Then the Cookie The validity period of is the current session , however , You set up AuthenticationProperties.IsPersistent = true To show that Cookie It's persistent , This leads to ambiguity , actually Cookie No persistence , But the code thinks it's persistent . therefore , To solve this ambiguity ,Cookie.Expiration It's banned , And a new one ExpireTimeSpan attribute , It can be used as the validity period of the bill , It can still be in Cookie Of Expires and Max-Age Are not set, but AuthenticationProperties.IsPersistent = true Under the circumstances , Set the value to Cookie Of Expires attribute , bring Cookie Also persistent .
Let's see the login effect :
No choice “ Remember me ” when :
choice “ Remember me ” when :
Explore other features by yourself !
Here is SignInAsync Simulation of core internal details of , See more details AuthenticationService and CookieAuthenticationHandler:
reasonml
public class AccountController : Controller
{
private readonly IOptionsMonitor<CookieAuthenticationOptions> _cookieAuthOptionsMonitor;
public AccountController(IOptionsMonitor<CookieAuthenticationOptions> cookieAuthOptions)
{
_cookieAuthOptionsMonitor = cookieAuthOptions;
}
[HttpPost]
public async Task<IActionResult> Login([FromForm] LoginViewModel input)
{
// ...
var options = _cookieAuthOptionsMonitor.Get(CookieAuthenticationDefaults.AuthenticationScheme);
var ticket = new AuthenticationTicket(principal, properties, CookieAuthenticationDefaults.AuthenticationScheme);
// ticket encryption
var cookieValue = options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding(HttpContext));
// CookieOptions Whatever new A the , In fact, it should be options and ticket The configuration of is transformed into CookieOptions
options.CookieManager.AppendResponseCookie(HttpContext, options.Cookie.Name, cookieValue, new CookieOptions());
// ...
}
}
User logout
Logging out is easier , Will be Cookie eliminate , I will not repeat :
csharp
[HttpPost]
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync();
return Redirect("/");
}
You can see it's called “auth” Of Cookie Cleared :

thus , A simple one based on Cookie The identity authentication function of is realized .
to grant authorization (Authorization)
Add authorization middleware
To use authorization , Need to go through first UseAuthorization Add authorization middleware ——AuthorizationMiddleware:
csharp
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
// Authentication middleware
app.UseAuthentication();
// Authorization middleware
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
UseAuthorizationMake sure to putUseRoutingandUseAuthenticationafter , Because authorization middleware needsEndpoint. in addition , And put it inUseEndpointsBefore , Otherwise, the request arrives Controller Before , Will not execute authorization middleware .
Authorization configuration
Now? , Authorization middleware has been added , Now you need to ConfigureServices Method to add services needed for authorization and make additional configuration .
csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.InvokeHandlersAfterFailure = true;
});
}
}
DefaultPolicy: Default authorization policy , The default isnew AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(), That is, only users who pass identity authentication can be authorized .InvokeHandlersAfterFailure: When there are multiple authorization processors , If one of them fails , Whether the subsequent processors will continue to execute . The default istrue, The execution will continue .
Url Add Authorization
Now? , We require users to log in before they can access /Home/Privacy, Add features to it [Authorize], No incoming policy is required policy, Just use the default policy :
csharp
public class HomeController : Controller
{
[HttpGet]
[Authorize]
public IActionResult Privacy()
{
return View();
}
}

You can try to visit
HttpContext.User, It is actually created when we log inClaimsPrincipal.
overall situation Cookie Strategy
in addition , We can go through UseCookiePolicy in the light of Cookie Policies are configured globally . It should be noted that ,CookiePolicyMiddleware It will only work on the middleware added after it , So try to put it in the front position .
csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Cookie Overall strategy
services.AddCookiePolicy(options =>
{
options.OnAppendCookie = context =>
{
Console.WriteLine("------------------ On Append Cookie --------------------");
Console.WriteLine($"Name: {context.CookieName}\tValue: {context.CookieValue}");
};
options.OnDeleteCookie = context =>
{
Console.WriteLine("------------------ On Delete Cookie --------------------");
Console.WriteLine($"Name: {context.CookieName}");
};
});
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
// Cookie Policy middleware
app.UseCookiePolicy();
// Authentication middleware
app.UseAuthentication();
// Authorization middleware
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Optimization and improvement
Optimize Claim To reduce authentication Cookie Volume
When the user logs in , After the verification is passed , Will add Claims, among “ type ” It is provided by Microsoft ClaimTypes:
csharp
new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString("N")),
new Claim(ClaimTypes.Name, input.UserName)
Carefully, you will find that ,ClaimTypes The value of is too long :
csharp
public static class ClaimTypes
{
public const string Name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";
public const string NameIdentifier = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
}
We can use JwtClaimTypes To optimize :
csharp
public static class JwtClaimTypes
{
public const string Id = "id";
public const string Name = "name";
}
install IdentityModel package
cli
Install-Package IdentityModel
Replace , Pay attention to creating
ClaimsIdentityThe instance specifiesNameandRoleThe type of , suchHttpContext.User.Identity.NameandHttpContext.User.IsInRole(string role)For normal use :
csharp
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, JwtClaimTypes.Name, JwtClaimTypes.Role);
identity.AddClaims(new[]
{
new Claim(JwtClaimTypes.Id, Guid.NewGuid().ToString("N")),
new Claim(JwtClaimTypes.Name, input.UserName)
});
Store... On the server side Session Information
Maybe , You still think Cookie It's too big , And along with Cookie The increase of information stored in , It's going to get bigger and bigger , Then you can consider the conversation (Session) The information is stored in the server to solve , This also protects data security to a certain extent .
The plan is very simple , We save the session information, that is, the authentication ticket, on the server instead of Cookie,Cookie You only need to store one SessionId. When the request is sent to the server , Will get SessionId, Through it , You can get the complete Session Information .
There are various storage media for session information , It could be memory 、 It can also be distributed storage middleware , Such as Redis etc. , Next, I will take memory as an example (Redis Can be found in my sample program source code , No post here ).
stay CookieAuthenticationOptions in , There is one SessionStore, The type is ITicketStore, Used to define the storage of the session , Next, let's implement it :
csharp
public class MemoryCacheTicketStore : ITicketStore
{
private const string KeyPrefix = "AuthSessionStore-";
private readonly IMemoryCache _cache;
private readonly TimeSpan _defaultExpireTimeSpan;
public MemoryCacheTicketStore(TimeSpan defaultExpireTimeSpan, MemoryCacheOptions options = null)
{
options ??= new MemoryCacheOptions();
_cache = new MemoryCache(options);
_defaultExpireTimeSpan = defaultExpireTimeSpan;
}
public async Task<string> StoreAsync(AuthenticationTicket ticket)
{
var guid = Guid.NewGuid();
var key = KeyPrefix + guid.ToString("N");
await RenewAsync(key, ticket);
return key;
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var options = new MemoryCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
{
options.SetAbsoluteExpiration(expiresUtc.Value);
}
else
{
options.SetSlidingExpiration(_defaultExpireTimeSpan);
}
_cache.Set(key, ticket, options);
return Task.CompletedTask;
}
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
_cache.TryGetValue(key, out AuthenticationTicket ticket);
return Task.FromResult(ticket);
}
public Task RemoveAsync(string key)
{
_cache.Remove(key);
return Task.CompletedTask;
}
}
then , Only need to CookieAuthenticationOptions.SessionStore Just assign a value :
gradle
options.SessionStore = new MemoryCacheTicketStore(options.ExpireTimeSpan);
The following is a stored in Cookie Medium SessionId Example , Although it is still very long , But it will not grow as the amount of information increases :
text
CfDJ8OGRqoEUgBZEu4m5Q8NfuATXjRKivKy7CR-oPpx2SaNJ8n1GWyBbPhNTEQzzIbZ62DqJPuxKtBJ752GqNxod9U5paaI_aQdH9EOH8nvgrinjvdHTneeKlhBvamEQrq7nA1e3wJOuQwFXRJASUphkS3kQzvc4-Upz27AAfoD510MC7YiwlhyxWl7agb8F0eeiilxAHDn4gskVqshu2hc5ENQAJNjXpa0yVaseryvsPrbukv5jqGC12WuUVe1cYhBIdWHHT61ZJcNtvNOAdtVlVA7i7RCJUBxNCUAhB-mw_s7R4GsNbU8aW7Ye9H-tx5067w
Good article recommends
Cookie
Samesite
Secure
Cookie Samesite analysis
Cookie Of SameSite attribute - Ruan Yifeng
CSRF The end of loopholes ? About Cookie SameSite What you have to know
Understanding "same-site" and "same-origin"
Cookie Of Secure attribute
Set-Cookie
In a cluster environment , What you have to pay attention to ASP.NET Core Data Protection Mechanism
Please stamp the source code XXTk.Auth.Samples.Cookies.Web
边栏推荐
- Response对象
- 美团8年经验之谈,测试工程师如何进阶(自动化、性能、测开)
- 跳转语句与调试程序
- MySql 数据库表名命名规则---方便自动转换工具转换
- C语言基础知识梳理(一)
- Figure 8 sequence of crystal head connection of network cable
- Redis pseudo cluster one click deployment script - pro test available
- 理解ASP.NET Core - 基于Cookie的身份认证(Authentication)
- Script of Nacos current limiting query
- 记一次 .NET 某智能交通后台服务 CPU爆高分析
猜你喜欢

【视觉SLAM】ORB-SLAM: Tracking and Mapping Recognizable Features

Question 300 Leçon 6 type quadratique

Custom events in components

网络安全等级保护2.0标准解析

软件测试基本概念篇

李宏毅机器学习2022-HW1

TZC 1283: 简单排序 —— 堆排序

Interpretation of ultra fast deep lane detection with hybrid anchor driven ordinal classification
C语言详解系列——函数的认识(1)库函数,自定义函数

How Alibaba cloud resolves a domain name to another domain name
随机推荐
12 open source background management systems suitable for outsourcing projects
Interpretation of ultra fast deep lane detection with hybrid anchor driven ordinal classification
Why can't we write really reusable C /f code?
C# IValueConverter接口用法举例
数据湖:Delta Lake介绍
SVG、canvas、绘制线段和填充多边形、矩形、曲线的绘制和填充
资源池以及资源池化是什么意思?
PyQt5_ Qlistwidget paging multiple selection control
HBV parameter extraction and fitting [draft]
[Delphi] a simple method to make the installation icon of the control panel (translation)
Clion + mingw64 configure C language development environment visual studio installation
【无标题】
XSSGAME小游戏(XSS学习)level1-15
kex_ exchange_ Identification: read: connection reset by peer imperfect solution (one)
mysql log理解
SQLZOO——SELECT from WORLD Tutorial
Interest rate in installment payment
Common neural network parameters and calculations
数据湖:从数据仓库看数据湖
【视觉SLAM】ORB-SLAM: Tracking and Mapping Recognizable Features