OpenIddict是否在HttpContext中存储身份验证失败原因?
问题描述
我有一个使用OpenIddict.Validation.AspNetCore和Bearer令牌的RESTful应用,ASP.NET控制器会评估令牌(若存在)但不强制身份验证(无令牌也可请求公开数据),未设置[Authorize]特性。仅当令牌验证成功时才返回更多机密数据,身份验证信息取自HttpContext.User.Identity.IsAuthenticated,同时结合请求头是否存在令牌的情况。
想问的是:OpenIddict是否会将身份验证失败的原因(导致IsAuthenticated为false)存储在HttpContext对象中,例如:无Bearer令牌、签名无效、签名有效但令牌过期等,以便做出更细致的响应?
补充说明:我已调整方案,在令牌无效时返回正确的HTTP 401状态,但仍想了解是否可提取失败原因。
回答
是的,OpenIddict会将身份验证失败的详细原因存储在HttpContext中,你可以通过两种常用方式获取:
- 直接读取验证结果对象
OpenIddict完成验证流程后,会把OpenIddictValidationResult实例存入HttpContext.Items集合,键为typeof(OpenIddictValidationResult).FullName。你可以直接取出这个对象,查看Errors属性获取具体失败原因,示例代码如下:
if (HttpContext.Items.TryGetValue(typeof(OpenIddictValidationResult).FullName, out var resultObj) && resultObj is OpenIddictValidationResult validationResult) { if (!validationResult.IsValid) { var errorCode = validationResult.Errors.FirstOrDefault()?.Code; // 比如"invalid_token"、"expired_token" var errorDesc = validationResult.Errors.FirstOrDefault()?.Description; // 对应的错误描述 } }
- 通过验证事件拦截获取
如果你想在验证过程中就捕获失败原因,可以注册OpenIddictValidationEvents中的相关事件(比如OnAuthenticationFailed或OnChallenge),在事件处理逻辑中直接拿到错误详情,还可以把信息存入HttpContext.Items方便后续控制器使用:
services.AddOpenIddict() .AddValidation(options => { options.AddEventHandler<OpenIddictValidationEvents.AuthenticationFailed>(context => { var errorCode = context.Error; var errorDesc = context.ErrorDescription; context.HttpContext.Items["AuthFailureReason"] = $"{errorCode}: {errorDesc}"; return default; }); });
注意:当请求中没有携带Bearer令牌时,OpenIddict不会将其视为验证失败,此时OpenIddictValidationResult会是有效的状态,这种情况需要你自行检查请求头是否包含Authorization: Bearer来判断。
内容的提问来源于stack exchange,提问作者Ingmar
相关产品推荐
相关产品推荐

