1

我有一個oauth2資源服務器,它使用JwtBearerMiddleware來驗證訪問令牌。現在我不希望安全印記發生變化時訪問令牌無效。因爲它看起來像這個中間件不會自己驗證安全印章。jwtBearerMiddleware中的安全戳驗證程序

我發現SecurityStampValidator類似乎只驗證cookie身份驗證。

我在哪裏以及如何從我的json Web令牌驗證安全印章?


我目前的方式做到這一點的是當我註冊JwtBearerMiddleware以註冊OnTokenValidated事件的事件處理程序。在這個事件處理程序中,我簡單地查詢數據庫中的安全聲明並將其與令牌中的聲明進行比較。當安全戳不相同時,我只需將上下文的TicketSecurityToken設置爲null,並跳到下一個中​​間件,如果需要身份驗證,它將最終拋出401 http狀態碼。

app.UseJwtBearerAuthentication(new JwtBearerOptions 
{ 
    ... 
    Events = new JwtBearerEvents 
    { 
     OnTokenValidated = async (ctx) => 
     { 
      var securityStampClaim = ctx.Ticket.Principal.Claims.FirstOrDefault(claim => claim.Type == "AspNet.Identity.SecurityStamp"); 
      var subjectClaim = ctx.Ticket.Principal.Claims.FirstOrDefault(claim => claim.Type == OpenIdConnectConstants.Claims.Subject); 

      if (securityStampClaim == null || subjectClaim == null) 
       return; 

      var user = await userStore.FindByIdAsync(subjectClaim.Value, ctx.HttpContext.RequestAborted); 
      if (user?.SecurityStamp == securityStampClaim.Value) 
       return; 

      ctx.SecurityToken = null; 
      ctx.Ticket = null; 
      ctx.SkipToNextMiddleware(); 
     } 
    } 
}); 

這是應該怎麼做?

回答

1

這是應該怎麼做?

技術上,是的(你甚至可以用SignInManager.ValidateSecurityStampAsync(principal)來簡化你的代碼)。

這就是說,你應該認真考慮避免存儲安全郵票在JWT令牌,因爲它們不是用來確定令牌或cookie是否應被視爲已撤銷,他們也用只是「不透明」的字符串作爲ASP.NET Core Identity生成2FA令牌熵的唯一來源:如果您將它們按原樣存儲在JWT中,則可以通過惡意的第三方客戶端應用程序輕鬆提取它們,並用於預測有效的2FA代碼登錄用戶。

這是一個已知問題,但AFAIK,沒有計劃解決它:https://github.com/aspnet/Identity/issues/626

如果要將安全標記存儲在訪問令牌中,請考慮使用OpenIddict的默認(加密)格式,該格式與ASP.NET Core對其加密的身份驗證Cookie使用的格式完全相同。

+0

爲什麼asp身份證在理賠原則中存儲安全戳呢? 並且用每個驗證郵票的請求來訪問數據庫效率不高嗎? –