日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

实践剖析.NET Core如何支持Cookie滑动过期和JWT混合认证、授权

發布時間:2023/12/4 asp.net 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实践剖析.NET Core如何支持Cookie滑动过期和JWT混合认证、授权 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【導讀】為防止JWT Token被竊取,我們將Token置于Cookie中,但若與第三方對接,調用我方接口進行認證、授權此時仍需將Token置于請求頭,通過實踐并聯系理論,我們繼續開始整活

首先我們實現Cookie認證,然后再次引入JWT,最后在結合二者使用時聯系其他我們可能需要注意的事項

Cookie認證

在startup中我們添加cookie認證服務,如下:

services.AddAuthentication(options?=> {options.DefaultAuthenticateScheme?=?CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultChallengeScheme?=?CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie(options?=> {options.ExpireTimeSpan?=?TimeSpan.FromMinutes(1);options.Cookie.Name?=?"user-session";options.SlidingExpiration?=?true; });

接下來則是使用認證和授權中間件,注意將其置于路由和終結點終結點之間,否則啟動也會有明確異常提示

app.UseRouting();app.UseAuthentication();app.UseAuthorization();app.UseEndpoints(endpoints?=> {...... });

我們給出測試視圖頁,并要求認證即控制器添加特性

[Authorize] public?class?HomeController?:?Controller {public?IActionResult?Index(){return?View();} }

當進入首頁,未認證默認進入account/login,那么接下來創建該視圖

public?class?AccountController?:?Controller {[AllowAnonymous]public?IActionResult?Login(){return?View();}...... }

我們啟動程序先看看效果

如上圖,自動跳轉至登錄頁,此時我們點擊模擬登錄按鈕,發起請求去模擬登錄(發起ajax請求代碼就占不用篇幅給出了)

///?<summary> ///?模擬登錄 ///?</summary> ///?<returns></returns> [HttpPost] [AllowAnonymous] public?async?Task<IActionResult>?TestLogin() {var?claims?=?new?Claim[]{new?Claim(ClaimTypes.Name,?"Jeffcky"),};var?claimsIdentity?=?new?ClaimsIdentity(claims,?"Login");await?HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,?new?ClaimsPrincipal(claimsIdentity));return?Ok(); }

上述無非就是構建身份以及該身份下所具有的身份屬性,類似個人身份證唯一標識個人,身份證上各個信息即表示如上聲明

同時呢,肯定要調用上下文去登錄,在整個會話未過期之前,根據認證方案獲取對應處理方式,最后將相關信息進行存儲等等,有興趣的童鞋可以去了解其實現細節哈

當我們請求過后,再次訪問首頁,將看到生成當前會話信息,同時我們將會話過期設置為1分鐘,在1分鐘內未進行會話,將自動重定向至登錄頁

注意如上標注并沒有值,那么這個值可以設置嗎?當然可以,在開始配置時我們并未給出,那么這個屬性又代表什么含義呢?

options.Cookie.MaxAge?=?TimeSpan.FromMinutes(2);

那么結合ExpireTimeSpan和MaxAge使用,到底代表什么意思呢?我們暫且撇開滑動過期設置

ExpireTimeSpan表示用戶身份認證票據的生命周期,它是認證cookie的有效負載,存儲的cookie值是一段加密字符串,在每次請求時,web應用程序都會根據請求對其進行解密

MaxAge控制著cookie的生命周期,若cookie過期,瀏覽器將會自動清除,如果沒有設置該值,實質上它的生命周期就是ExpireTimeSpan,那么它到底有何意義呢?

上述我們設置票據的生命周期為1分鐘,同時我們控制cookie的生命周期為2分鐘,若在2分鐘內關閉瀏覽器或重啟web應用程序,此時cookie生命周期并未過期,所以仍將處于會話狀態即無需登錄,若未設置MaxAge,關閉瀏覽器或重啟后將自動清除其值即需登錄,當然一切前提是未手動清除瀏覽器cookie

問題又來了,在配置cookie選項中,還有一個也可以設置過期的屬性

options.Cookie.Expiration?=?TimeSpan.FromMinutes(3);

當配置ExpireTimeSpan或同時配置MaxAge時,無需設置Expiration,因為會拋出異常

JWT認證

上述已經實現Cookie認證,那么在與第三方進行對接時,我們要使用JWT認證,我們又該如何處理呢?

首先我們添加JWT認證服務

.AddJwtBearer(options?=> {options.TokenValidationParameters?=?new?TokenValidationParameters{ValidateIssuerSigningKey?=?true,IssuerSigningKey?=?new?SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456")),ValidateIssuer?=?true,ValidIssuer?=?"http://localhost:5000",ValidateAudience?=?true,ValidAudience?=?"http://localhost:5001",ValidateLifetime?=?true,ClockSkew?=?TimeSpan.FromMinutes(5)}; });

將JWT Token置于cookie中,此前文章已有講解,這里我們直接給出代碼,先生成Token

private?string?GenerateToken(Claim[]?claims) {var?key?=?new?SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456"));var?token?=?new?JwtSecurityToken(issuer:?"http://localhost:5000",audience:?"http://localhost:5001",claims:?claims,notBefore:?DateTime.Now,expires:?DateTime.Now.AddMinutes(5),signingCredentials:?new?SigningCredentials(key,?SecurityAlgorithms.HmacSha256));return?new?JwtSecurityTokenHandler().WriteToken(token); }

在登錄方法中,將其寫入響應cookie中,如下這般

///?<summary> ///?模擬登錄 ///?</summary> ///?<returns></returns> [HttpPost] [AllowAnonymous] public?async?Task<IActionResult>?TestLogin() {var?claims?=?new?Claim[]{new?Claim(ClaimTypes.Name,?"Jeffcky"),};var?claimsIdentity?=?new?ClaimsIdentity(claims,?"Login");Response.Cookies.Append("x-access-token",?GenerateToken(claims),new?CookieOptions(){Path?=?"/",HttpOnly?=?true});await?HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,?new?ClaimsPrincipal(claimsIdentity));return?Ok(); }

那么JWT是如何驗證Token的呢?默認是從請求去取Bearer Token值,若成功取到這賦值給如下context.Token,所以此時我們需要手動從cookie中取出token并賦值

options.Events?=?new?JwtBearerEvents {OnMessageReceived?=?context?=>{var?accessToken?=?context.Request.Cookies["x-access-token"];if?(!string.IsNullOrEmpty(accessToken)){context.Token?=?accessToken;}return?Task.CompletedTask;} };

一切已就緒,接下來我們寫個api接口測試驗證看看

[Authorize("Bearer")] [Route("api/[controller]/[action]")] [ApiController] public?class?JwtController?:?ControllerBase {[HttpGet]public?IActionResult?Test(){return?Ok("test?jwt");} }

思考一下,我們通過Postman模擬測試,會返回401嗎?結果會是怎樣的呢?

問題不大,主要在于該特性參數為聲明指定策略,但我們需要指定認證方案即scheme,修改成如下:

如此在與第三方對接時,請求返回token,后續將token置于請求頭中即可驗證通過,同時上述取cookie中token并手動賦值,對于對接第三方則是多余,不過是為了諸多其他原因而已

[Authorize(AuthenticationSchemes?=?"Bearer,Cookies")]

注意混合認證方案設置存在順序,后者將覆蓋前者即如上設置,此時將走cookie認證

滑動過期思考擴展

若我們實現基于Cookie滑動過期,同時使用signalr進行數據推送,勢必存在問題,因為會一直刷新會話,那么將導致會話永不過期問題,從安全層面角度考慮,我們該如何處理呢?

我們知道票據生命周期存儲在上下文AuthenticationProperties屬性中,所以在配置Cookie選項事件中我們可以進行自定義處理

public?class?CookieAuthenticationEventsExetensions?:?CookieAuthenticationEvents {private?const?string?TicketIssuedTicks?=?nameof(TicketIssuedTicks);public?override?async?Task?SigningIn(CookieSigningInContext?context){context.Properties.SetString(TicketIssuedTicks,DateTimeOffset.UtcNow.Ticks.ToString());await?base.SigningIn(context);}public?override?async?Task?ValidatePrincipal(CookieValidatePrincipalContext?context){var?ticketIssuedTicksValue?=?context.Properties.GetString(TicketIssuedTicks);if?(ticketIssuedTicksValue?is?null?||!long.TryParse(ticketIssuedTicksValue,?out?var?ticketIssuedTicks)){await?RejectPrincipalAsync(context);return;}var?ticketIssuedUtc?=new?DateTimeOffset(ticketIssuedTicks,?TimeSpan.FromHours(0));if?(DateTimeOffset.UtcNow?-?ticketIssuedUtc?>?TimeSpan.FromDays(3)){await?RejectPrincipalAsync(context);return;}await?base.ValidatePrincipal(context);}private?static?async?Task?RejectPrincipalAsync(CookieValidatePrincipalContext?context){context.RejectPrincipal();await?context.HttpContext.SignOutAsync();} }

在添加Cookie服務時,有對應事件選項,使用如下

options.EventsType?=?typeof(CookieAuthenticationEventsExetensions);

擴展事件實現表示在第一次會話到當前時間截止超過3天,則自動重定向至登錄頁,最后將上述擴展事件進行注冊即可

總結

以上是生活随笔為你收集整理的实践剖析.NET Core如何支持Cookie滑动过期和JWT混合认证、授权的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。