成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

實(shí)踐剖析.NET Core 如何支持 Cookie 滑動(dòng)過(guò)期和 JWT 混合認(rèn)證、授權(quán)

開(kāi)發(fā) 后端
MaxAge控制著cookie的生命周期,若cookie過(guò)期,瀏覽器將會(huì)自動(dòng)清除,如果沒(méi)有設(shè)置該值,實(shí)質(zhì)上它的生命周期就是ExpireTimeSpan,那么它到底有何意義呢?

首先我們實(shí)現(xiàn)Cookie認(rèn)證,然后再次引入JWT,最后在結(jié)合二者使用時(shí)聯(lián)系其他我們可能需要注意的事項(xiàng)

Cookie認(rèn)證

在startup中我們添加cookie認(rèn)證服務(wù),如下:

  1. services.AddAuthentication(options => 
  2.     options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; 
  3.     options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; 
  4. }) 
  5. .AddCookie(options => 
  6.     options.ExpireTimeSpan = TimeSpan.FromMinutes(1); 
  7.     options.Cookie.Name = "user-session"
  8.     options.SlidingExpiration = true
  9. }); 

接下來(lái)則是使用認(rèn)證和授權(quán)中間件,注意將其置于路由和終結(jié)點(diǎn)終結(jié)點(diǎn)之間,否則啟動(dòng)也會(huì)有明確異常提示

  1. app.UseRouting(); 
  2.  
  3. app.UseAuthentication(); 
  4.  
  5. app.UseAuthorization(); 
  6.  
  7. app.UseEndpoints(endpoints => 
  8.   ...... 
  9. }); 

我們給出測(cè)試視圖頁(yè),并要求認(rèn)證即控制器添加特性

  1. [Authorize] 
  2. public class HomeController : Controller 
  3.     public IActionResult Index() 
  4.     { 
  5.         return View(); 
  6.     } 

當(dāng)進(jìn)入首頁(yè),未認(rèn)證默認(rèn)進(jìn)入account/login,那么接下來(lái)創(chuàng)建該視圖

  1. public class AccountController : Controller 
  2.     [AllowAnonymous] 
  3.     public IActionResult Login() 
  4.     { 
  5.       return View(); 
  6.     } 
  7.     ...... 

我們啟動(dòng)程序先看看效果

如上圖,自動(dòng)跳轉(zhuǎn)至登錄頁(yè),此時(shí)我們點(diǎn)擊模擬登錄按鈕,發(fā)起請(qǐng)求去模擬登錄(發(fā)起ajax請(qǐng)求代碼就占不用篇幅給出了)

  1. /// <summary> 
  2. /// 模擬登錄 
  3. /// </summary> 
  4. /// <returns></returns
  5. [HttpPost] 
  6. [AllowAnonymous] 
  7. public async Task<IActionResult> TestLogin() 
  8.     var claims = new Claim[] 
  9.     { 
  10.       new Claim(ClaimTypes.Name"Jeffcky"), 
  11.     }; 
  12.  
  13.     var claimsIdentity = new ClaimsIdentity(claims, "Login"); 
  14.  
  15.     await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity)); 
  16.  
  17.     return Ok(); 

上述無(wú)非就是構(gòu)建身份以及該身份下所具有的身份屬性,類似個(gè)人身份證唯一標(biāo)識(shí)個(gè)人,身份證上各個(gè)信息即表示如上聲明

同時(shí)呢,肯定要調(diào)用上下文去登錄,在整個(gè)會(huì)話未過(guò)期之前,根據(jù)認(rèn)證方案獲取對(duì)應(yīng)處理方式,最后將相關(guān)信息進(jìn)行存儲(chǔ)等等,有興趣的童鞋可以去了解其實(shí)現(xiàn)細(xì)節(jié)哈

當(dāng)我們請(qǐng)求過(guò)后,再次訪問(wèn)首頁(yè),將看到生成當(dāng)前會(huì)話信息,同時(shí)我們將會(huì)話過(guò)期設(shè)置為1分鐘,在1分鐘內(nèi)未進(jìn)行會(huì)話,將自動(dòng)重定向至登錄頁(yè)

注意如上標(biāo)注并沒(méi)有值,那么這個(gè)值可以設(shè)置嗎?當(dāng)然可以,在開(kāi)始配置時(shí)我們并未給出,那么這個(gè)屬性又代表什么含義呢?

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

那么結(jié)合ExpireTimeSpan和MaxAge使用,到底代表什么意思呢?我們暫且撇開(kāi)滑動(dòng)過(guò)期設(shè)置

ExpireTimeSpan表示用戶身份認(rèn)證票據(jù)的生命周期,它是認(rèn)證cookie的有效負(fù)載,存儲(chǔ)的cookie值是一段加密字符串,在每次請(qǐng)求時(shí),web應(yīng)用程序都會(huì)根據(jù)請(qǐng)求對(duì)其進(jìn)行解密

MaxAge控制著cookie的生命周期,若cookie過(guò)期,瀏覽器將會(huì)自動(dòng)清除,如果沒(méi)有設(shè)置該值,實(shí)質(zhì)上它的生命周期就是ExpireTimeSpan,那么它到底有何意義呢?

上述我們?cè)O(shè)置票據(jù)的生命周期為1分鐘,同時(shí)我們控制cookie的生命周期為2分鐘,若在2分鐘內(nèi)關(guān)閉瀏覽器或重啟web應(yīng)用程序,此時(shí)cookie生命周期并未過(guò)期,所以仍將處于會(huì)話狀態(tài)即無(wú)需登錄,若未設(shè)置MaxAge,關(guān)閉瀏覽器或重啟后將自動(dòng)清除其值即需登錄,當(dāng)然一切前提是未手動(dòng)清除瀏覽器cookie

問(wèn)題又來(lái)了,在配置cookie選項(xiàng)中,還有一個(gè)也可以設(shè)置過(guò)期的屬性

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

當(dāng)配置ExpireTimeSpan或同時(shí)配置MaxAge時(shí),無(wú)需設(shè)置Expiration,因?yàn)闀?huì)拋出異常

JWT認(rèn)證

上述已經(jīng)實(shí)現(xiàn)Cookie認(rèn)證,那么在與第三方進(jìn)行對(duì)接時(shí),我們要使用JWT認(rèn)證,我們又該如何處理呢?

首先我們添加JWT認(rèn)證服務(wù)

  1. .AddJwtBearer(options => 
  2.     options.TokenValidationParameters = new TokenValidationParameters 
  3.     { 
  4.       ValidateIssuerSigningKey = true
  5.       IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456")), 
  6.       ValidateIssuer = true
  7.       ValidIssuer = "http://localhost:5000"
  8.       ValidateAudience = true
  9.       ValidAudience = "http://localhost:5001"
  10.       ValidateLifetime = true
  11.       ClockSkew = TimeSpan.FromMinutes(5) 
  12.     }; 
  13. }); 

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

  1. private string GenerateToken(Claim[] claims) 
  2.     var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456")); 
  3.  
  4.     var token = new JwtSecurityToken( 
  5.       issuer: "http://localhost:5000"
  6.       audience: "http://localhost:5001"
  7.       claims: claims, 
  8.       notBefore: DateTime.Now, 
  9.       expires: DateTime.Now.AddMinutes(5), 
  10.       signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256) 
  11.     ); 
  12.  
  13.     return new JwtSecurityTokenHandler().WriteToken(token); 

在登錄方法中,將其寫(xiě)入響應(yīng)cookie中,如下這般

  1. /// <summary> 
  2. /// 模擬登錄 
  3. /// </summary> 
  4. /// <returns></returns
  5. [HttpPost] 
  6. [AllowAnonymous] 
  7. public async Task<IActionResult> TestLogin() 
  8.     var claims = new Claim[] 
  9.     { 
  10.       new Claim(ClaimTypes.Name"Jeffcky"), 
  11.     }; 
  12.  
  13.     var claimsIdentity = new ClaimsIdentity(claims, "Login"); 
  14.  
  15.     Response.Cookies.Append("x-access-token", GenerateToken(claims), 
  16.       new CookieOptions() 
  17.       { 
  18.         Path = "/"
  19.         HttpOnly = true 
  20.       }); 
  21.  
  22.     await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity)); 
  23.  
  24.  return Ok(); 

去取Bearer Token值,若成功取到這賦值給如下context.Token,所以此時(shí)我們需要手動(dòng)從cookie中取出token并賦值

  1. options.Events = new JwtBearerEvents 
  2.     OnMessageReceived = context => 
  3.     { 
  4.         var accessToken = context.Request.Cookies["x-access-token"]; 
  5.  
  6.         if (!string.IsNullOrEmpty(accessToken)) 
  7.         { 
  8.             context.Token = accessToken; 
  9.         } 
  10.  
  11.         return Task.CompletedTask; 
  12.     } 
  13. }; 

一切已就緒,接下來(lái)我們寫(xiě)個(gè)api接口測(cè)試驗(yàn)證看看

  1. [Authorize("Bearer")] 
  2. [Route("api/[controller]/[action]")] 
  3. [ApiController] 
  4. public class JwtController : ControllerBase 
  5.     [HttpGet] 
  6.     public IActionResult Test() 
  7.     { 
  8.       return Ok("test jwt"); 
  9.     } 

思考一下,我們通過(guò)Postman模擬測(cè)試,會(huì)返回401嗎?結(jié)果會(huì)是怎樣的呢?

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

如此在與第三方對(duì)接時(shí),請(qǐng)求返回token,后續(xù)將token置于請(qǐng)求頭中即可驗(yàn)證通過(guò),同時(shí)上述取cookie中token并手動(dòng)賦值,對(duì)于對(duì)接第三方則是多余,不過(guò)是為了諸多其他原因而已

  1. [Authorize(AuthenticationSchemes = "Bearer,Cookies")] 

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

滑動(dòng)過(guò)期思考擴(kuò)展

若我們實(shí)現(xiàn)基于Cookie滑動(dòng)過(guò)期,同時(shí)使用signalr進(jìn)行數(shù)據(jù)推送,勢(shì)必存在問(wèn)題,因?yàn)闀?huì)一直刷新會(huì)話,那么將導(dǎo)致會(huì)話永不過(guò)期問(wèn)題,從安全層面角度考慮,我們?cè)撊绾翁幚砟?

我們知道票據(jù)生命周期存儲(chǔ)在上下文AuthenticationProperties屬性中,所以在配置Cookie選項(xiàng)事件中我們可以進(jìn)行自定義處理

  1. public class CookieAuthenticationEventsExetensions : CookieAuthenticationEvents 
  2.     private const string TicketIssuedTicks = nameof(TicketIssuedTicks); 
  3.  
  4.     public override async Task SigningIn(CookieSigningInContext context) 
  5.     { 
  6.         context.Properties.SetString( 
  7.           TicketIssuedTicks, 
  8.           DateTimeOffset.UtcNow.Ticks.ToString()); 
  9.  
  10.         await base.SigningIn(context); 
  11.     } 
  12.  
  13.     public override async Task ValidatePrincipal( 
  14.       CookieValidatePrincipalContext context) 
  15.     { 
  16.         var ticketIssuedTicksValue = context 
  17.           .Properties.GetString(TicketIssuedTicks); 
  18.  
  19.         if (ticketIssuedTicksValue is null || 
  20.           !long.TryParse(ticketIssuedTicksValue, out var ticketIssuedTicks)) 
  21.         { 
  22.           await RejectPrincipalAsync(context); 
  23.           return
  24.         } 
  25.  
  26.         var ticketIssuedUtc = 
  27.           new DateTimeOffset(ticketIssuedTicks, TimeSpan.FromHours(0)); 
  28.  
  29.         if (DateTimeOffset.UtcNow - ticketIssuedUtc > TimeSpan.FromDays(3)) 
  30.         { 
  31.           await RejectPrincipalAsync(context); 
  32.           return
  33.         } 
  34.  
  35.         await base.ValidatePrincipal(context); 
  36.     } 
  37.  
  38.     private static async Task RejectPrincipalAsync( 
  39.       CookieValidatePrincipalContext context) 
  40.     { 
  41.         context.RejectPrincipal(); 
  42.         await context.HttpContext.SignOutAsync(); 
  43.     } 

在添加Cookie服務(wù)時(shí),有對(duì)應(yīng)事件選項(xiàng),使用如下

  1. options.EventsType = typeof(CookieAuthenticationEventsExetensions); 

 

擴(kuò)展事件實(shí)現(xiàn)表示在第一次會(huì)話到當(dāng)前時(shí)間截止超過(guò)3天,則自動(dòng)重定向至登錄頁(yè),最后將上述擴(kuò)展事件進(jìn)行注冊(cè)即可

 

責(zé)任編輯:武曉燕 來(lái)源: JeffckyShare
相關(guān)推薦

2019-11-08 08:00:00

ASP .NETASP .NET Cocookie

2024-09-09 07:37:51

AspJWT權(quán)限

2021-07-11 17:17:08

.NET 授權(quán)自定義

2021-02-17 08:51:55

cookie身份驗(yàn)證

2019-03-27 15:51:51

API 認(rèn)證授權(quán)

2009-07-21 15:47:19

2024-03-14 11:57:53

.NET Core反射開(kāi)發(fā)

2025-01-10 00:27:32

2009-12-03 10:00:46

Linux系統(tǒng)啟動(dòng)

2015-01-13 10:01:03

AWS市場(chǎng)亞馬遜云平臺(tái)

2024-12-30 00:15:48

ASP.NET安全

2021-12-05 18:22:20

.NETLS Cipher套件

2021-08-09 08:53:30

HTTP狀態(tài)化協(xié)議

2009-08-05 18:30:36

Session和CooASP.NET表單

2024-05-17 09:51:11

2024-12-30 12:00:00

.NET Core依賴注入屬性注入

2024-03-27 14:43:07

.NET Core后端監(jiān)控可觀測(cè)性

2022-04-21 09:00:00

API安全密鑰

2021-07-11 12:12:49

.NETJWTjson

2024-10-08 10:11:57

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久网站黄 | 日韩av免费在线电影 | 免费观看黄a一级视频 | 婷婷综合| 特黄色一级毛片 | 久久99这里只有精品 | 91视频官网| 一级黄色夫妻生活 | 久久这里有精品 | 日韩在线一区二区三区 | 欧美日一区 | 在线成人www免费观看视频 | 国产主播第一页 | 国产精品国产成人国产三级 | 91人人在线 | 国产在线观看不卡一区二区三区 | 青青草在线视频免费观看 | 亚洲一区精品视频 | 午夜爽爽爽男女免费观看 | 神马福利 | 日韩精品在线网站 | 亚洲一区二区三区在线免费观看 | 2021天天躁夜夜看 | 超级乱淫av片免费播放 | 亚洲成人免费观看 | 欧美午夜影院 | 午夜视频一区二区 | 久久99精品久久久久久 | 四虎影 | av在线免费观看网址 | 国产成人精品久久二区二区91 | 欧美国产亚洲一区二区 | 无码日韩精品一区二区免费 | 欧美激情在线一区二区三区 | 国产成人精品一区二区三区在线观看 | 国产欧美日韩一区二区三区在线观看 | 久久久久久色 | 羞羞视频网站免费看 | 久久成人精品视频 | 欧美午夜激情在线 | 亚洲精品自在在线观看 |