我已經使用以下代碼實作了一個支持 jwt 令牌授權的 api:
services.AddAuthentication(bearerScheme)
.AddJwtBearer(bearerScheme, config =>
{
config.Authority = authority;
config.Audience = resourceId;
我還實作了一個自定義屬性,該屬性提供了進一步的基于權限的驗證,以及它自己的 AuthorizationPolicyProvider 和 AuthorizationHandler。發送有效的令牌沒有問題。默認 JwtSecurityTokenHandler 在我的客戶處理程式觸發之前觸發并驗證令牌,并使用令牌驗證用戶權限。然而,發送過期的令牌并沒有像我期望的那樣作業。似乎發生的是 JwtSecurityTokenHandler 觸發并拒絕帶有以下錯誤的令牌 - 正如預期的那樣
IDX10223: Lifetime validation failed. The token is expired.
我不明白的是為什么我的 AuthorizationHandler 然后被觸發,然后使用無效的訪問令牌來聯系另一個 api 并因為令牌無效而失敗。理想情況下,我想:
- 由于令牌失敗,讓 jwt 驗證停止并回傳 401 錯誤,或
- 以某種方式能夠在我的處理程式中獲得 jwt 驗證的結果并自己拋出錯誤
有人知道我怎么做嗎?我很想了解為什么在身份驗證失敗時也會處理控制器方法上的屬性,因為在身份驗證失敗后繼續對我來說似乎很奇怪?
uj5u.com熱心網友回復:
簡答
最有可能的是,.AddJwtBearer()以某種方式最終設定的配置(JwtBearerOptions).TokenValidationParameters.ValidateLifetime被設定為false.
另一種可能性是服務器上的系統時鐘有問題(很少發生)。
要使其在Authentication步驟中失敗,請嘗試
.AddJwtBearer(options =>
{
//... Some other config
options.TokenValidationParameters.ValidateLifetime = true;
//... In case options.TokenValidationParameters.ValidateLifetime still got override somehow, do this
options.TokenValidationParameters.LifetimeValidator = (nbf, exp, _, _) => nbf < DateTime.UtcNow && exp > DateTime.UtcNow;
}
)
引擎蓋下
我們必須從AuthenticationMiddleware開始。Schemes.GetRequestHandlerSchemesAsync()不會收回任何東西進行迭代(如果有一些好奇,請進一步調查IAuthenticationRequestHandlervs IAuthenticationHandler)。
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();將回傳我們都知道的默認身份驗證方案。然后,它呼叫context.AuthenticateAsync(),這是一個擴展這里,化妝用的AuthenticationService。現在AuthenticationHandler將作為經典。除了將 jwt 令牌轉換為ClaimPrincipal物件外,什么都不做。如果它在此流程步驟中沒有快速失敗,它將流向AuthorizationMiddleware,這肯定會評估我們的策略(也就是說,AuthorizationHandler無論如何都會觸發代碼塊)。
所以,我們現在要做的就是讓從 jwt 到ClaimPrincipalobject的轉換程序失敗。那樣的話,AuthorizationHandler就不會火了,這可以完成簡答部分。
uj5u.com熱心網友回復:
在 ASP.NET Core 中,成功的身份驗證默認情況下不是授權的要求,因為它們用于不同的目的:
Authentication: 恢復用戶身份Authorization: 決定是否授予訪問權限
在請求管道中(如果這是觸發授權的地方),授權中間件嘗試使用授權策略(如果有)上的給定身份驗證方案來恢復用戶的身份。如果沒有一個認證方案成功,認證結果就是 NO RESULT。在這種情況下,將針對未經身份驗證的用戶評估授權策略。
如果您要強制執行經過身份驗證的用戶,則需要在使用RequireAuthenticatedUser以下命令構建策略時明確指定它:
new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
您還可以檢查User.Identity.IsAuthenticated以確定用戶是否在您的授權處理代碼中進行了身份驗證,并且僅針對經過身份驗證的場景呼叫您的 API。
您還可以選擇忽略未經身份驗證的用戶并讓其他授權處理程式根據其他因素決定“匿名用戶”是否應該有權訪問資源,或者通過從您的代碼回傳失敗的授權結果來大聲失敗。
如果您對源代碼感興趣,請查看PolicyEvaluator.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/331452.html
