ASP.NET Core 使用Cookie驗(yàn)證身份的示例代碼
ASP.NET Core 1.x提供了通過(guò)Cookie 中間件將用戶(hù)主體序列化為一個(gè)加密的Cookie,然后在后續(xù)請(qǐng)求中驗(yàn)證Cookie并重新創(chuàng)建主體,并將其分配給HttpContext.User屬性。如果您要提供自己的登錄界面和用戶(hù)數(shù)據(jù)庫(kù),可以使用作為獨(dú)立功能的Cookie中間件。
ASP.NET Core 2.x的一個(gè)主要變化是不再存在Cookie中間件。取而代之的是在Startup.cs文件中的Configure方法中的調(diào)用UseAuthentication方法會(huì)添加設(shè)置HttpContext.User屬性的 AuthenticationMiddleware 中間件。
添加配置
ASP.NET Core 1.x
按下列步驟操作:
在您的項(xiàng)目中安裝Microsoft.AspNetCore.Authentication.CookiesNuGet包。此包包含Cookie中間件。
在Startup.cs文件中的Configure方法中添加下面的行,在app.UseMvc()語(yǔ)句之前:
app.UseCookieAuthentication(new CookieAuthenticationOptions() { AccessDeniedPath = "/Account/Forbidden/", AuthenticationScheme = "MyCookieAuthenticationScheme", AutomaticAuthenticate = true, AutomaticChallenge = true, LoginPath = "/Account/Unauthorized/" });
ASP.NET Core 2.x
按下列步驟操作:
如果不使用Microsoft.AspNetCore.All 元包,則在您的項(xiàng)目中安裝2.0版的Microsoft.AspNetCore.Authentication.CookiesNuGet
包。
在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/"; });
上面的代碼片段配置了以下部分或全部選項(xiàng):
- AccessDeniedPath - 當(dāng)用戶(hù)嘗試訪(fǎng)問(wèn)資源但沒(méi)有通過(guò)任何授權(quán)策略時(shí),這是請(qǐng)求會(huì)重定向的相對(duì)路徑資源。
- AuthenticationScheme - 這是一個(gè)已知的特定Cookie認(rèn)證方案的值。當(dāng)有多個(gè)Cookie驗(yàn)證實(shí)例,并且您想限制對(duì)一個(gè)實(shí)例的授權(quán)時(shí),這就非常有用。
- AutomaticAuthenticate - 此標(biāo)識(shí)僅適用于ASP.NET Core 1.x。它表示Cookie身份驗(yàn)證應(yīng)在每個(gè)請(qǐng)求上運(yùn)行,并嘗試驗(yàn)證和重建序列化主體。
- AutomaticChallenge - 此標(biāo)識(shí)僅適用于ASP.NET Core 1.x。這表示當(dāng)授權(quán)失敗時(shí),1.x Cookie認(rèn)證應(yīng)將瀏覽器重定向到LoginPath或AccessDeniedPath。
- LoginPath - 當(dāng)用戶(hù)嘗試訪(fǎng)問(wèn)資源但尚未認(rèn)證時(shí),這是請(qǐng)求重定向的相對(duì)路徑。
其它選項(xiàng)包括為Cookie認(rèn)證創(chuàng)建的設(shè)置選項(xiàng),身份驗(yàn)證的Cookie的名稱(chēng),Cookie的域和Cookie各種安全屬性。默認(rèn)情況下,Cookie身份驗(yàn)證為其創(chuàng)建的任何Cookie使用適當(dāng)?shù)陌踩x項(xiàng),例如:
- 設(shè)置HttpOnly標(biāo)志以防止客戶(hù)端JavaScript中訪(fǎng)問(wèn)Cookie
- 如果請(qǐng)求是通過(guò)HTTPS訪(fǎng)問(wèn),則將Cookie限制為HTTPS
創(chuàng)建身份認(rèn)證Cookie
要?jiǎng)?chuàng)建一個(gè)保存用戶(hù)信息的cookie,您必須構(gòu)建一個(gè)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)建一個(gè)加密的Cookie并將其添加到當(dāng)前響應(yīng)中。在調(diào)用SignInAsync時(shí),必須在配置中指定的AuthenticationScheme。
順便提一下,使用的加密方式是ASP.NET Core的Data Protection系統(tǒng)。如果您在多臺(tái)機(jī)器上進(jìn)行托管、負(fù)載平衡或使用Web集群,則需要配置Data Protection才能使用相同的密鑰和應(yīng)用程序標(biāo)識(shí)符。
Signing out(登出)
要退出當(dāng)前用戶(hù)并刪除其Cookie,請(qǐng)?jiān)诳刂破髦姓{(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,它將成為唯一的身份來(lái)源。即使您在服務(wù)系統(tǒng)中禁用用戶(hù),Cookie身份驗(yàn)證也無(wú)法了解此信息,只要Cookie有效,用戶(hù)仍可登錄。
Cookie認(rèn)證在其選項(xiàng)中提供了一系列事件。ValidateAsync()事件可用于攔截和重寫(xiě)Cookie身份驗(yàn)證。
可以考慮在后端用戶(hù)數(shù)據(jù)庫(kù)中增加LastChanged列。為了在數(shù)據(jù)庫(kù)更改時(shí)使Cookie無(wú)效,您應(yīng)該首先在創(chuàng)建Cookie時(shí)添加一個(gè)LastChanged包含當(dāng)前值的聲明。數(shù)據(jù)庫(kù)更改時(shí),更新LastChanged例的值。
要重寫(xiě)ValidateAsync()事件的實(shí)現(xiàn),您必須編寫(xiě)一個(gè)具有以下簽名的方法:
Task ValidateAsync(CookieValidatePrincipalContext context);
ASP.NET Core Identity 在SecurityStampValidator實(shí)現(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<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("MyCookieAuthenticationScheme"); } } }
然后,在Startup.cs文件中的Configure方法中將Cokie認(rèn)證配置進(jìn)行重寫(xiě):
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<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.SignOutAsync("MyCookieAuthenticationScheme"); } } }
然后,將在Startup.cs的ConfigureServices方法中將Cookie服務(wù)注冊(cè)進(jìn)行配置:
services.AddAuthentication("MyCookieAuthenticationScheme") .AddCookie(options => { options.Events = new CookieAuthenticationEvents { OnValidatePrincipal = LastChangedValidator.ValidateAsync }; });
如果要非破壞性地更新用戶(hù)主體,可以調(diào)用context.ReplacePrincipal(),并將context.ShouldRenew屬性設(shè)置為true。
Cookie設(shè)置選項(xiàng)
CookieAuthenticationOptions類(lèi)提供了各種配置選項(xiàng),在創(chuàng)建時(shí)調(diào)整Cookie的配置。
ASP.NET Core 1.x
- ClaimsIssuer是由中間件創(chuàng)建的任何聲明時(shí)使用的Issuer屬性。
- CookieDomain是提供Cookie的域名。默認(rèn)情況下,這是發(fā)送請(qǐng)求的主機(jī)名。瀏覽器僅將Cookie提供給匹配的主機(jī)名。您可能希望對(duì)此進(jìn)行調(diào)整,以便您的域中的任何主機(jī)都可以使用Cookie。例如,將Cookie域名設(shè)置為.contoso.com,可以使用Cookie的域名有contoso.com、www.contoso.com、staging.www.contoso.com等。
- CookieHttpOnly是一個(gè)標(biāo)識(shí),指定Cookie是否只能由服務(wù)器訪(fǎng)問(wèn)。默認(rèn)為true。如果您的應(yīng)用程序具有Cross-Site Scripting(XSS)的問(wèn)題,更改此值可能會(huì)導(dǎo)致Cookie被盜用。
- CookiePath可用于隔離在相同主機(jī)名上運(yùn)行的應(yīng)用程序。如果你有一個(gè)應(yīng)用程序在/app1中運(yùn)行,并希望限制發(fā)送的Cookie只發(fā)送到該應(yīng)用程序,那么您應(yīng)該將CookiePath屬性設(shè)置為/app1。通過(guò)這樣做,Cookie只適用于對(duì)/app1或其下任何內(nèi)容的請(qǐng)求。
- CookieSecure是一個(gè)標(biāo)識(shí),表示創(chuàng)建的Cookie是否應(yīng)該被限制為HTTPS,HTTP或HTTPS,或與請(qǐng)求相同的協(xié)議。默認(rèn)為SameAsRequest。
- ExpireTimeSpan是TimeSpan類(lèi)型,在此時(shí)間段之后Cookie將過(guò)期。將當(dāng)前日期加上此時(shí)間段為創(chuàng)建Cookie的到期日期。
- SlidingExpiration是一個(gè)標(biāo)識(shí),指示當(dāng)超過(guò)一半的ExpireTimeSpan間隔時(shí),Cookie到期日期是否復(fù)位。新的到期日是當(dāng)前時(shí)間加上ExpireTimespan。調(diào)用SignInAsync時(shí),可以使用AuthenticationProperties類(lèi)設(shè)置絕對(duì)到期時(shí)間。絕對(duì)到期時(shí)間可以通過(guò)限制認(rèn)證Cookie有效的時(shí)間來(lái)提高應(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)記為過(guò)時(shí),并且在CookieAuthenticationOptions類(lèi)中引入了一種類(lèi)型為CookieBuilder新的Cookie屬性。建議您遷移到2.x API。
- ClaimsIssuer是由Cookie認(rèn)證創(chuàng)建的任何聲明時(shí)使用的Issuer屬性。
- CookieBuilder.Domain是提供Cookie的域名。默認(rèn)情況下,這是發(fā)送請(qǐng)求的主機(jī)名。瀏覽器僅將Cookie提供給匹配的主機(jī)名。您可能希望對(duì)此進(jìn)行調(diào)整,以便您的域中的任何主機(jī)都可以使用Cookie。例如,將Cookie域名設(shè)置為.contoso.com,可以使用Cookie的域名有contoso.com、www.contoso.com、staging.www.contoso.com等
- CookieBuilder.HttpOnly是一個(gè)標(biāo)識(shí),指定Cookie是否只能由服務(wù)器訪(fǎng)問(wèn)。默認(rèn)為true。如果您的應(yīng)用程序具有Cross-Site Scripting(XSS)的問(wèn)題,更改此值可能會(huì)導(dǎo)致Cookie被盜用。
- CookieBuilder.Path可用于隔離在相同主機(jī)名上運(yùn)行的應(yīng)用程序。如果你有一個(gè)應(yīng)用程序在/app1中運(yùn)行,并希望限制發(fā)送的Cookie只發(fā)送到該應(yīng)用程序,那么您應(yīng)該將CookiePath屬性設(shè)置為/app1。通過(guò)這樣做,Cookie只適用于對(duì)/app1或其下任何內(nèi)容的請(qǐng)求。
- CookieBuilder.SameSite表示瀏覽器是否允許Cookie被附加到同一站點(diǎn)或跨站點(diǎn)的請(qǐng)求。默認(rèn)為SameSiteMode.Lax。
- CookieBuilder.SecurePolicy是一個(gè)標(biāo)識(shí),表示創(chuàng)建的Cookie是否應(yīng)該被限制為HTTPS,HTTP或HTTPS,或與請(qǐng)求相同的協(xié)議。默認(rèn)為SameAsRequest。
- ExpireTimeSpan是TimeSpan類(lèi)型,在此時(shí)間段之后Cookie將過(guò)期。將當(dāng)前日期加上此時(shí)間段為創(chuàng)建Cookie的到期日期。
- SlidingExpiration是一個(gè)標(biāo)識(shí),指示當(dāng)超過(guò)一半的ExpireTimeSpan間隔時(shí),Cookie到期日期是否復(fù)位。新的到期日是當(dāng)前時(shí)間加上ExpireTimespan。調(diào)用SignInAsync時(shí),可以使用AuthenticationProperties類(lèi)設(shè)置絕對(duì)到期時(shí)間。絕對(duì)到期時(shí)間可以通過(guò)限制認(rèn)證Cookie有效的時(shí)間來(lái)提高應(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和絕對(duì)到期時(shí)間
您可能希望Cookie在瀏覽器會(huì)話(huà)中持續(xù)存在,并希望設(shè)置身份和Cookie傳輸?shù)慕^對(duì)過(guò)期時(shí)間。這種持久性應(yīng)該只能是用戶(hù)顯示同意,在登錄時(shí)的“記住我”復(fù)選框或類(lèi)似的機(jī)制啟用。您可以通過(guò)在創(chuàng)建身份認(rèn)證Cookie時(shí)調(diào)用的SignInAsync方法中使用AuthenticationProperties參數(shù)來(lái)執(zhí)行這些操作。例如:
ASP.NET Core 1.x
await HttpContext.Authentication.SignInAsync( "MyCookieAuthenticationScheme", principal, new AuthenticationProperties { IsPersistent = true });
上述代碼片段中使用的AuthenticationProperties類(lèi),位于Microsoft.AspNetCore.Http.Authentication命名空間中。
ASP.NET Core 2.x
await HttpContext.SignInAsync( "MyCookieAuthenticationScheme", principal, new AuthenticationProperties { IsPersistent = true });
上述代碼片段中使用的AuthenticationProperties類(lèi),位于Microsoft.AspNetCore.Authentication命名空間中。
上面的代碼段創(chuàng)建一個(gè)身份和相應(yīng)的Cookie,直到瀏覽器關(guān)閉。以前通過(guò)Cookie設(shè)置選項(xiàng)配置的任何滑動(dòng)過(guò)期設(shè)置仍然有效。如果Cookie在瀏覽器關(guān)閉時(shí)過(guò)期,瀏覽器會(huì)在重新啟動(dòng)后清除它。如果Cookie在瀏覽器關(guān)閉時(shí)過(guò)期,瀏覽器會(huì)在重新啟動(dòng)后清除它。
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)建一個(gè)持續(xù)20分鐘的身份和相應(yīng)的cookie。這將忽略以前通過(guò)Cookie設(shè)置選項(xiàng)配置的任何滑動(dòng)過(guò)期設(shè)置。
ExpiresUtc和IsPersistent屬性是互斥的。
原文:《Using Cookie Authentication without ASP.NET Core Identity》
翻譯:Sweet Tang
本文地址:http://www.cnblogs.com/tdfblog/p/aspnet-core-security-authentication-cookie.html
到此這篇關(guān)于ASP.NET Core 使用Cookie驗(yàn)證身份的示例代碼的文章就介紹到這了,更多相關(guān)ASP.NET Core Cookie驗(yàn)證身份內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- ASP.NET?Core中Cookie驗(yàn)證身份用法詳解
- asp.core?同時(shí)兼容JWT身份驗(yàn)證和Cookies?身份驗(yàn)證兩種模式(示例詳解)
- .NET?Core支持Cookie和JWT混合認(rèn)證、授權(quán)的方法
- asp.net core3.1cookie和jwt混合認(rèn)證授權(quán)實(shí)現(xiàn)多種身份驗(yàn)證方案
- asp.net core中如何使用cookie身份驗(yàn)證
- 3分鐘快速學(xué)會(huì)在ASP.NET Core MVC中如何使用Cookie
- ASP.NET學(xué)習(xí)CORE中使用Cookie身份認(rèn)證方法
- 詳解在ASP.NET Core 中使用Cookie中間件
- 詳解ASP.NET與ASP.NET Core用戶(hù)驗(yàn)證Cookie并存解決方案
- ASP.NET?Core在WebApi項(xiàng)目中使用Cookie
相關(guān)文章
云服務(wù)器下搭建ASP.NET Core環(huán)境
本文給大家分享的是在云服務(wù)器上搭建ASP.NET Core環(huán)境以及成功運(yùn)行官網(wǎng)DEMO的教程,十分的細(xì)致全面,有需要的小伙伴可以參考下。2016-07-07Asp.Net 生成靜態(tài)頁(yè)并實(shí)現(xiàn)分頁(yè)效果
Asp.Net 生成靜態(tài)頁(yè)并實(shí)現(xiàn)分頁(yè)效果的代碼,需要的朋友可以參考下。2010-04-04Asp.Net實(shí)現(xiàn)404頁(yè)面與301重定向的方法
這篇文章主要介紹了Asp.Net實(shí)現(xiàn)404頁(yè)面與301重定向的方法,較為詳細(xì)的分析了404頁(yè)面的原理與針對(duì)404錯(cuò)誤與301跳轉(zhuǎn)的實(shí)現(xiàn)方法,是非常實(shí)用的技巧,需要的朋友可以參考下2014-11-11aspxgridview CustomButtonCallback 不支持彈出消息提示解決方法
aspxgridveiw是devexpress的一個(gè)grid控件,使用起來(lái)還不錯(cuò),不能再 CustomButtonCallback 事件中使用response.write,具體的解決方法如下,感興趣的朋友可以參考下哈2013-06-06利用sender的Parent獲取GridView中的當(dāng)前行(獲取gridview的值)
這篇文章主要介紹了利用sender的Parent獲取GridView中的當(dāng)前行的方法,大家參考使用吧2014-01-01CodeFirst從零開(kāi)始搭建Asp.Net Core2.0網(wǎng)站
這篇文章主要為大家詳細(xì)介紹了CodeFirst從零開(kāi)始搭建Asp.Net Core2.0網(wǎng)站的詳細(xì)過(guò)程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07探究ASP.NET Core Middleware實(shí)現(xiàn)方法
這篇文章主要介紹了探究ASP.NET Core Middleware實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02