網(wǎng)站首頁 編程語言 正文
ASP.NET Core 1.x提供了通過Cookie?中間件將用戶主體序列化為一個加密的Cookie,然后在后續(xù)請求中驗證Cookie并重新創(chuàng)建主體,并將其分配給HttpContext.User
屬性。如果您要提供自己的登錄界面和用戶數(shù)據(jù)庫,可以使用作為獨(dú)立功能的Cookie中間件。
ASP.NET Core 2.x的一個主要變化是不再存在Cookie中間件。取而代之的是在Startup.cs文件中的Configure
方法中的調(diào)用UseAuthentication
方法會添加設(shè)置HttpContext.User
屬性的?AuthenticationMiddleware?中間件。
添加配置
ASP.NET Core 1.x
按下列步驟操作:
在您的項目中安裝
Microsoft.AspNetCore.Authentication.Cookies
NuGet包。此包包含Cookie中間件。在Startup.cs文件中的
Configure
方法中添加下面的行,在app.UseMvc()
語句之前:
app.UseCookieAuthentication(new CookieAuthenticationOptions() { AccessDeniedPath = "/Account/Forbidden/", AuthenticationScheme = "MyCookieAuthenticationScheme", AutomaticAuthenticate = true, AutomaticChallenge = true, LoginPath = "/Account/Unauthorized/" });
ASP.NET Core 2.x
按下列步驟操作:
如果不使用
Microsoft.AspNetCore.All
?元包,則在您的項目中安裝2.0版的Microsoft.AspNetCore.Authentication.Cookies
NuGet包。在Startup.cs文件中的
Configure
方法中調(diào)用UseAuthentication
方法:
app.UseAuthentication();
- 在Startup.cs文件中的
ConfigureServices
方法中調(diào)用AddAuthentication
和AddCookie
方法:
services.AddAuthentication("MyCookieAuthenticationScheme") .AddCookie("MyCookieAuthenticationScheme", options => { options.AccessDeniedPath = "/Account/Forbidden/"; options.LoginPath = "/Account/Unauthorized/"; });
上面的代碼片段配置了以下部分或全部選項:
-
AccessDeniedPath
?- 當(dāng)用戶嘗試訪問資源但沒有通過任何授權(quán)策略時,這是請求會重定向的相對路徑資源。 -
AuthenticationScheme
?- 這是一個已知的特定Cookie認(rèn)證方案的值。當(dāng)有多個Cookie驗證實例,并且您想限制對一個實例的授權(quán)時,這就非常有用。 -
AutomaticAuthenticate
?- 此標(biāo)識僅適用于ASP.NET Core 1.x。它表示Cookie身份驗證應(yīng)在每個請求上運(yùn)行,并嘗試驗證和重建序列化主體。 -
AutomaticChallenge
?- 此標(biāo)識僅適用于ASP.NET Core 1.x。這表示當(dāng)授權(quán)失敗時,1.x Cookie認(rèn)證應(yīng)將瀏覽器重定向到LoginPath
或AccessDeniedPath
。 -
LoginPath
?- 當(dāng)用戶嘗試訪問資源但尚未認(rèn)證時,這是請求重定向的相對路徑。
其它選項包括為Cookie認(rèn)證創(chuàng)建的設(shè)置選項,身份驗證的Cookie的名稱,Cookie的域和Cookie各種安全屬性。默認(rèn)情況下,Cookie身份驗證為其創(chuàng)建的任何Cookie使用適當(dāng)?shù)陌踩x項,例如:
- 設(shè)置HttpOnly標(biāo)志以防止客戶端JavaScript中訪問Cookie
- 如果請求是通過HTTPS訪問,則將Cookie限制為HTTPS
創(chuàng)建身份認(rèn)證Cookie
要創(chuàng)建一個保存用戶信息的cookie,您必須構(gòu)建一個ClaimsPrincipal?保存您希望序列化到Cookie中的信息。
ASP.NET Core 1.x
await HttpContext.Authentication.SignInAsync("MyCookieAuthenticationScheme", principal);
ASP.NET Core 2.x
await HttpContext.SignInAsync("MyCookieAuthenticationScheme", principal);
這將創(chuàng)建一個加密的Cookie并將其添加到當(dāng)前響應(yīng)中。在調(diào)用SignInAsync
時,必須在配置中指定的AuthenticationScheme
。
順便提一下,使用的加密方式是ASP.NET Core的Data Protection系統(tǒng)。如果您在多臺機(jī)器上進(jìn)行托管、負(fù)載平衡或使用Web集群,則需要配置Data Protection才能使用相同的密鑰和應(yīng)用程序標(biāo)識符。
Signing out(登出)
要退出當(dāng)前用戶并刪除其Cookie,請在控制器中調(diào)用以下方法:
ASP.NET Core 1.x
await HttpContext.Authentication.SignOutAsync("MyCookieAuthenticationScheme");
ASP.NET Core 2.x
await HttpContext.SignOutAsync("MyCookieAuthenticationScheme");
服務(wù)端變化反饋
警告:?一旦創(chuàng)建了認(rèn)證的Cookie,它將成為唯一的身份來源。即使您在服務(wù)系統(tǒng)中禁用用戶,Cookie身份驗證也無法了解此信息,只要Cookie有效,用戶仍可登錄。
Cookie認(rèn)證在其選項中提供了一系列事件。ValidateAsync()
事件可用于攔截和重寫Cookie身份驗證。
可以考慮在后端用戶數(shù)據(jù)庫中增加LastChanged
列。為了在數(shù)據(jù)庫更改時使Cookie無效,您應(yīng)該首先在創(chuàng)建Cookie時添加一個LastChanged
包含當(dāng)前值的聲明。數(shù)據(jù)庫更改時,更新LastChanged
例的值。
要重寫ValidateAsync()
事件的實現(xiàn),您必須編寫一個具有以下簽名的方法:
Task ValidateAsync(CookieValidatePrincipalContext context);
ASP.NET Core Identity 在SecurityStampValidator
實現(xiàn)了這一邏輯,鏈接地址。示例如下所示:
ASP.NET Core 1.x
public static class LastChangedValidator { public static async Task ValidateAsync(CookieValidatePrincipalContext context) { // Pull database from registered DI services. var userRepository = context.HttpContext.RequestServices.GetRequiredService(); 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("MyCookieAuthenticationScheme"); } } }
然后,在Startup.cs文件中的Configure
方法中將Cokie認(rèn)證配置進(jìn)行重寫:
app.UseCookieAuthentication(new CookieAuthenticationOptions { Events = new CookieAuthenticationEvents { OnValidatePrincipal = LastChangedValidator.ValidateAsync } });
ASP.NET Core 2.x
public static class LastChangedValidator { public static async Task ValidateAsync(CookieValidatePrincipalContext context) { // Pull database from registered DI services. var userRepository = context.HttpContext.RequestServices.GetRequiredService(); 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.SignOutAsync("MyCookieAuthenticationScheme"); } } }
然后,將在Startup.cs的ConfigureServices
方法中將Cookie服務(wù)注冊進(jìn)行配置:
services.AddAuthentication("MyCookieAuthenticationScheme") .AddCookie(options => { options.Events = new CookieAuthenticationEvents { OnValidatePrincipal = LastChangedValidator.ValidateAsync }; });
如果要非破壞性地更新用戶主體,可以調(diào)用context.ReplacePrincipal()
,并將context.ShouldRenew
屬性設(shè)置為true
。
Cookie設(shè)置選項
CookieAuthenticationOptions類提供了各種配置選項,在創(chuàng)建時調(diào)整Cookie的配置。
ASP.NET Core 1.x
-
ClaimsIssuer
是由中間件創(chuàng)建的任何聲明時使用的Issuer屬性。 -
CookieDomain
是提供Cookie的域名。默認(rèn)情況下,這是發(fā)送請求的主機(jī)名。瀏覽器僅將Cookie提供給匹配的主機(jī)名。您可能希望對此進(jìn)行調(diào)整,以便您的域中的任何主機(jī)都可以使用Cookie。例如,將Cookie域名設(shè)置為.contoso.com
,可以使用Cookie的域名有contoso.com
、www.contoso.com
、staging.www.contoso.com
等。 -
CookieHttpOnly
是一個標(biāo)識,指定Cookie是否只能由服務(wù)器訪問。默認(rèn)為true
。如果您的應(yīng)用程序具有Cross-Site Scripting(XSS)的問題,更改此值可能會導(dǎo)致Cookie被盜用。 -
CookiePath
可用于隔離在相同主機(jī)名上運(yùn)行的應(yīng)用程序。如果你有一個應(yīng)用程序在/app1
中運(yùn)行,并希望限制發(fā)送的Cookie只發(fā)送到該應(yīng)用程序,那么您應(yīng)該將CookiePath
屬性設(shè)置為/app1
。通過這樣做,Cookie只適用于對/app1
或其下任何內(nèi)容的請求。 -
CookieSecure
是一個標(biāo)識,表示創(chuàng)建的Cookie是否應(yīng)該被限制為HTTPS,HTTP或HTTPS,或與請求相同的協(xié)議。默認(rèn)為SameAsRequest
。 -
ExpireTimeSpan
是TimeSpan
類型,在此時間段之后Cookie將過期。將當(dāng)前日期加上此時間段為創(chuàng)建Cookie的到期日期。 -
SlidingExpiration
是一個標(biāo)識,指示當(dāng)超過一半的ExpireTimeSpan
間隔時,Cookie到期日期是否復(fù)位。新的到期日是當(dāng)前時間加上ExpireTimespan
。調(diào)用SignInAsync
時,可以使用AuthenticationProperties
類設(shè)置絕對到期時間。絕對到期時間可以通過限制認(rèn)證Cookie有效的時間來提高應(yīng)用程序的安全性。
在Startup.cs文件中的Configure
方法中使用CookieAuthenticationOptions
的例子如下:
app.UseCookieAuthentication(new CookieAuthenticationOptions { CookieName = "AuthCookie", CookieDomain = "contoso.com", CookiePath = "/", CookieHttpOnly = true, CookieSecure = CookieSecurePolicy.Always });
ASP.NET Core 2.x
ASP.NET Core 2.x 統(tǒng)一了用于配置Cookie的API。1.x API已被標(biāo)記為過時,并且在CookieAuthenticationOptions
類中引入了一種類型為CookieBuilder
新的Cookie
屬性。建議您遷移到2.x API。
-
ClaimsIssuer
是由Cookie認(rèn)證創(chuàng)建的任何聲明時使用的Issuer屬性。 -
CookieBuilder.Domain
是提供Cookie的域名。默認(rèn)情況下,這是發(fā)送請求的主機(jī)名。瀏覽器僅將Cookie提供給匹配的主機(jī)名。您可能希望對此進(jìn)行調(diào)整,以便您的域中的任何主機(jī)都可以使用Cookie。例如,將Cookie域名設(shè)置為.contoso.com
,可以使用Cookie的域名有contoso.com
、www.contoso.com
、staging.www.contoso.com
等 -
CookieBuilder.HttpOnly
是一個標(biāo)識,指定Cookie是否只能由服務(wù)器訪問。默認(rèn)為true
。如果您的應(yīng)用程序具有Cross-Site Scripting(XSS)的問題,更改此值可能會導(dǎo)致Cookie被盜用。 -
CookieBuilder.Path
可用于隔離在相同主機(jī)名上運(yùn)行的應(yīng)用程序。如果你有一個應(yīng)用程序在/app1
中運(yùn)行,并希望限制發(fā)送的Cookie只發(fā)送到該應(yīng)用程序,那么您應(yīng)該將CookiePath
屬性設(shè)置為/app1
。通過這樣做,Cookie只適用于對/app1
或其下任何內(nèi)容的請求。 -
CookieBuilder.SameSite
表示瀏覽器是否允許Cookie被附加到同一站點(diǎn)或跨站點(diǎn)的請求。默認(rèn)為SameSiteMode.Lax
。 -
CookieBuilder.SecurePolicy
是一個標(biāo)識,表示創(chuàng)建的Cookie是否應(yīng)該被限制為HTTPS,HTTP或HTTPS,或與請求相同的協(xié)議。默認(rèn)為SameAsRequest
。 -
ExpireTimeSpan
是TimeSpan
類型,在此時間段之后Cookie將過期。將當(dāng)前日期加上此時間段為創(chuàng)建Cookie的到期日期。 -
SlidingExpiration
是一個標(biāo)識,指示當(dāng)超過一半的ExpireTimeSpan
間隔時,Cookie到期日期是否復(fù)位。新的到期日是當(dāng)前時間加上ExpireTimespan
。調(diào)用SignInAsync
時,可以使用AuthenticationProperties
類設(shè)置絕對到期時間。絕對到期時間可以通過限制認(rèn)證Cookie有效的時間來提高應(yīng)用程序的安全性。
在Startup.cs的ConfigureServices
方法中使用CookieAuthenticationOptions
的例子如下:
services.AddAuthentication() .AddCookie(options => { options.Cookie.Name = "AuthCookie"; options.Cookie.Domain = "contoso.com"; options.Cookie.Path = "/"; options.Cookie.HttpOnly = true; options.Cookie.SameSite = SameSiteMode.Lax; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; });
持久Cookie
您可能希望Cookie在瀏覽器會話中持續(xù)存在,并希望設(shè)置身份和Cookie傳輸?shù)慕^對過期時間。這種持久性應(yīng)該只能是用戶顯示同意,在登錄時的“記住我”復(fù)選框或類似的機(jī)制啟用。您可以通過在創(chuàng)建身份認(rèn)證Cookie時調(diào)用的SignInAsync
方法中使用AuthenticationProperties
參數(shù)來執(zhí)行這些操作。例如:
ASP.NET Core 1.x
await HttpContext.Authentication.SignInAsync( "MyCookieAuthenticationScheme", principal, new AuthenticationProperties { IsPersistent = true });
上述代碼片段中使用的AuthenticationProperties
類,位于Microsoft.AspNetCore.Http.Authentication
命名空間中。
ASP.NET Core 2.x
await HttpContext.SignInAsync( "MyCookieAuthenticationScheme", principal, new AuthenticationProperties { IsPersistent = true });
上述代碼片段中使用的AuthenticationProperties
類,位于Microsoft.AspNetCore.Authentication
命名空間中。
上面的代碼段創(chuàng)建一個身份和相應(yīng)的Cookie,直到瀏覽器關(guān)閉。以前通過Cookie設(shè)置選項配置的任何滑動過期設(shè)置仍然有效。如果Cookie在瀏覽器關(guān)閉時過期,瀏覽器會在重新啟動后清除它。如果Cookie在瀏覽器關(guān)閉時過期,瀏覽器會在重新啟動后清除它。
絕對到期時間
ASP.NET Core 1.x
await HttpContext.Authentication.SignInAsync( "MyCookieAuthenticationScheme", principal, new AuthenticationProperties { ExpiresUtc = DateTime.UtcNow.AddMinutes(20) });
ASP.NET Core 2.x
await HttpContext.SignInAsync( "MyCookieAuthenticationScheme", principal, new AuthenticationProperties { ExpiresUtc = DateTime.UtcNow.AddMinutes(20) });
上述代碼段創(chuàng)建一個持續(xù)20分鐘的身份和相應(yīng)的cookie。這將忽略以前通過Cookie設(shè)置選項配置的任何滑動過期設(shè)置。
ExpiresUtc
和IsPersistent
屬性是互斥的。
原文鏈接:https://www.cnblogs.com/tdfblog/p/aspnet-core-security-authentication-cookie.html
相關(guān)推薦
- 2022-12-12 Android?DataBinding類關(guān)系深入探究_Android
- 2022-08-26 淺談C++/C關(guān)于#define的那些奇奇怪怪的用法_C 語言
- 2022-11-04 SQL?Server還原完整備份和差異備份的操作過程_MsSql
- 2022-03-04 scss的calc計算表達(dá)式。沒有起作用是怎么回事
- 2022-12-29 C#使用Lambda表達(dá)式簡化代碼的示例詳解_C#教程
- 2022-11-25 命令行下執(zhí)行TypeScript文件的三種方法_基礎(chǔ)知識
- 2022-10-19 Android?webview加載H5方法詳細(xì)介紹_Android
- 2022-05-08 C++類中隱藏的幾個默認(rèn)函數(shù)你知道嗎_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支