ASP.NET Core 使用Cookie验证身份
ASP.NET Core 1.x提供了通過Cookie?中間件將用戶主體序列化為一個加密的Cookie,然后在后續請求中驗證Cookie并重新創建主體,并將其分配給HttpContext.User屬性。如果您要提供自己的登錄界面和用戶數據庫,可以使用作為獨立功能的Cookie中間件。
ASP.NET Core 2.x的一個主要變化是不再存在Cookie中間件。取而代之的是在Startup.cs文件中的Configure方法中的調用UseAuthentication方法會添加設置HttpContext.User屬性的?AuthenticationMiddleware?中間件。
添加配置
ASP.NET Core 1.x
按下列步驟操作:
在您的項目中安裝Microsoft.AspNetCore.Authentication.CookiesNuGet包。此包包含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.CookiesNuGet包。
在Startup.cs文件中的Configure方法中調用UseAuthentication方法:
? ?app.UseAuthentication();在Startup.cs文件中的ConfigureServices方法中調用AddAuthentication和AddCookie方法:
? ?services.AddAuthentication("MyCookieAuthenticationScheme").AddCookie("MyCookieAuthenticationScheme", options => {options.AccessDeniedPath = "/Account/Forbidden/";options.LoginPath = "/Account/Unauthorized/";});
上面的代碼片段配置了以下部分或全部選項:
AccessDeniedPath?- 當用戶嘗試訪問資源但沒有通過任何授權策略時,這是請求會重定向的相對路徑資源。
AuthenticationScheme?- 這是一個已知的特定Cookie認證方案的值。當有多個Cookie驗證實例,并且您想限制對一個實例的授權時,這就非常有用。
AutomaticAuthenticate?- 此標識僅適用于ASP.NET Core 1.x。它表示Cookie身份驗證應在每個請求上運行,并嘗試驗證和重建序列化主體。
AutomaticChallenge?- 此標識僅適用于ASP.NET Core 1.x。這表示當授權失敗時,1.x Cookie認證應將瀏覽器重定向到LoginPath或AccessDeniedPath。
LoginPath?- 當用戶嘗試訪問資源但尚未認證時,這是請求重定向的相對路徑。
其它選項包括為Cookie認證創建的設置選項,身份驗證的Cookie的名稱,Cookie的域和Cookie各種安全屬性。默認情況下,Cookie身份驗證為其創建的任何Cookie使用適當的安全選項,例如:
設置HttpOnly標志以防止客戶端JavaScript中訪問Cookie
如果請求是通過HTTPS訪問,則將Cookie限制為HTTPS
創建身份認證Cookie
要創建一個保存用戶信息的cookie,您必須構建一個ClaimsPrincipal?保存您希望序列化到Cookie中的信息。
ASP.NET Core 1.x
? ?await HttpContext.Authentication.SignInAsync("MyCookieAuthenticationScheme", principal);ASP.NET Core 2.x
? ?await HttpContext.SignInAsync("MyCookieAuthenticationScheme", principal);這將創建一個加密的Cookie并將其添加到當前響應中。在調用SignInAsync時,必須在配置中指定的AuthenticationScheme。
順便提一下,使用的加密方式是ASP.NET Core的Data Protection系統。如果您在多臺機器上進行托管、負載平衡或使用Web集群,則需要配置Data Protection才能使用相同的密鑰和應用程序標識符。
Signing out(登出)
要退出當前用戶并刪除其Cookie,請在控制器中調用以下方法:
ASP.NET Core 1.x
? ?await HttpContext.Authentication.SignOutAsync("MyCookieAuthenticationScheme");ASP.NET Core 2.x
? ?await HttpContext.SignOutAsync("MyCookieAuthenticationScheme");服務端變化反饋
警告:?一旦創建了認證的Cookie,它將成為唯一的身份來源。即使您在服務系統中禁用用戶,Cookie身份驗證也無法了解此信息,只要Cookie有效,用戶仍可登錄。
Cookie認證在其選項中提供了一系列事件。ValidateAsync()事件可用于攔截和重寫Cookie身份驗證。
可以考慮在后端用戶數據庫中增加LastChanged列。為了在數據庫更改時使Cookie無效,您應該首先在創建Cookie時添加一個LastChanged包含當前值的聲明。數據庫更改時,更新LastChanged例的值。
要重寫ValidateAsync()事件的實現,您必須編寫一個具有以下簽名的方法:
? ?Task ValidateAsync(CookieValidatePrincipalContext context);ASP.NET Core Identity 在SecurityStampValidator實現了這一邏輯,鏈接地址。示例如下所示:
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認證配置進行重寫:
? ?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服務注冊進行配置:
? ?services.AddAuthentication("MyCookieAuthenticationScheme").AddCookie(options =>{options.Events = new CookieAuthenticationEvents{OnValidatePrincipal = LastChangedValidator.ValidateAsync};});如果要非破壞性地更新用戶主體,可以調用context.ReplacePrincipal(),并將context.ShouldRenew屬性設置為true。
Cookie設置選項
CookieAuthenticationOptions類提供了各種配置選項,在創建時調整Cookie的配置。
ASP.NET Core 1.x
ClaimsIssuer是由中間件創建的任何聲明時使用的Issuer屬性。
CookieDomain是提供Cookie的域名。默認情況下,這是發送請求的主機名。瀏覽器僅將Cookie提供給匹配的主機名。您可能希望對此進行調整,以便您的域中的任何主機都可以使用Cookie。例如,將Cookie域名設置為.contoso.com,可以使用Cookie的域名有contoso.com、www.contoso.com、staging.www.contoso.com等。
CookieHttpOnly是一個標識,指定Cookie是否只能由服務器訪問。默認為true。如果您的應用程序具有Cross-Site Scripting(XSS)的問題,更改此值可能會導致Cookie被盜用。
CookiePath可用于隔離在相同主機名上運行的應用程序。如果你有一個應用程序在/app1中運行,并希望限制發送的Cookie只發送到該應用程序,那么您應該將CookiePath屬性設置為/app1。通過這樣做,Cookie只適用于對/app1或其下任何內容的請求。
CookieSecure是一個標識,表示創建的Cookie是否應該被限制為HTTPS,HTTP或HTTPS,或與請求相同的協議。默認為SameAsRequest。
ExpireTimeSpan是TimeSpan類型,在此時間段之后Cookie將過期。將當前日期加上此時間段為創建Cookie的到期日期。
SlidingExpiration是一個標識,指示當超過一半的ExpireTimeSpan間隔時,Cookie到期日期是否復位。新的到期日是當前時間加上ExpireTimespan。調用SignInAsync時,可以使用AuthenticationProperties類設置絕對到期時間。絕對到期時間可以通過限制認證Cookie有效的時間來提高應用程序的安全性。
在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 統一了用于配置Cookie的API。1.x API已被標記為過時,并且在CookieAuthenticationOptions類中引入了一種類型為CookieBuilder新的Cookie屬性。建議您遷移到2.x API。
ClaimsIssuer是由Cookie認證創建的任何聲明時使用的Issuer屬性。
CookieBuilder.Domain是提供Cookie的域名。默認情況下,這是發送請求的主機名。瀏覽器僅將Cookie提供給匹配的主機名。您可能希望對此進行調整,以便您的域中的任何主機都可以使用Cookie。例如,將Cookie域名設置為.contoso.com,可以使用Cookie的域名有contoso.com、www.contoso.com、staging.www.contoso.com等
CookieBuilder.HttpOnly是一個標識,指定Cookie是否只能由服務器訪問。默認為true。如果您的應用程序具有Cross-Site Scripting(XSS)的問題,更改此值可能會導致Cookie被盜用。
CookieBuilder.Path可用于隔離在相同主機名上運行的應用程序。如果你有一個應用程序在/app1中運行,并希望限制發送的Cookie只發送到該應用程序,那么您應該將CookiePath屬性設置為/app1。通過這樣做,Cookie只適用于對/app1或其下任何內容的請求。
CookieBuilder.SameSite表示瀏覽器是否允許Cookie被附加到同一站點或跨站點的請求。默認為SameSiteMode.Lax。
CookieBuilder.SecurePolicy是一個標識,表示創建的Cookie是否應該被限制為HTTPS,HTTP或HTTPS,或與請求相同的協議。默認為SameAsRequest。
ExpireTimeSpan是TimeSpan類型,在此時間段之后Cookie將過期。將當前日期加上此時間段為創建Cookie的到期日期。
SlidingExpiration是一個標識,指示當超過一半的ExpireTimeSpan間隔時,Cookie到期日期是否復位。新的到期日是當前時間加上ExpireTimespan。調用SignInAsync時,可以使用AuthenticationProperties類設置絕對到期時間。絕對到期時間可以通過限制認證Cookie有效的時間來提高應用程序的安全性。
在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在瀏覽器會話中持續存在,并希望設置身份和Cookie傳輸的絕對過期時間。這種持久性應該只能是用戶顯示同意,在登錄時的“記住我”復選框或類似的機制啟用。您可以通過在創建身份認證Cookie時調用的SignInAsync方法中使用AuthenticationProperties參數來執行這些操作。例如:
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命名空間中。
上面的代碼段創建一個身份和相應的Cookie,直到瀏覽器關閉。以前通過Cookie設置選項配置的任何滑動過期設置仍然有效。如果Cookie在瀏覽器關閉時過期,瀏覽器會在重新啟動后清除它。如果Cookie在瀏覽器關閉時過期,瀏覽器會在重新啟動后清除它。
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)});
上述代碼段創建一個持續20分鐘的身份和相應的cookie。這將忽略以前通過Cookie設置選項配置的任何滑動過期設置。
ExpiresUtc和IsPersistent屬性是互斥的。
原文:《Using Cookie Authentication without ASP.NET Core Identity》https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x
翻譯:Sweet Tang
本文地址:<http://www.cnblogs.com/tdfblog/p/aspnet-core-security-authentication-cookie.html?>
相關文章:?
.NET Core 2.0 正式發布信息匯總
.NET Standard 2.0 特性介紹和使用指南
.NET Core 2.0 的dll實時更新、https、依賴包變更問題及解決
.NET Core 2.0 特性介紹和使用指南
Entity Framework Core 2.0 新特性
體驗 PHP under .NET Core
.NET Core 2.0使用NLog
升級項目到.NET Core 2.0,在Linux上安裝Docker,并成功部署
解決Visual Studio For Mac Restore失敗的問題
ASP.NET Core 2.0 特性介紹和使用指南
.Net Core下通過Proxy 模式 使用 WCF
.NET Core 2.0 開源Office組件 NPOI
ASP.NET Core Razor頁面 vs MVC
Razor Page–Asp.Net Core 2.0新功能 ?Razor Page介紹
原文地址:http://www.cnblogs.com/inday/p/razor-page-in-asp-net-core-2.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的ASP.NET Core 使用Cookie验证身份的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core 2.0迁移技巧之Me
- 下一篇: asp.net core MVC 过滤器