【发布时间】:2022-03-04 03:39:38
【问题描述】:
我正在使用 Microsoft 记录的多个 JWT 不记名身份验证 一切正常,直到我将它放入具有需要可选身份验证的控制器方法的应用程序(appsettings.json 中的一个属性控制请求是否需要进行身份验证)
我正在使用我自己的实现IAsyncAuthorizationFilter的属性进行可选身份验证
public class OptionalAuthorizationAttribute: Attribute, IAsyncAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
SetUnauthorized(context);
}
public Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
SetUnauthorized(context);
return Task.CompletedTask;
}
private void SetUnauthorized(AuthorizationFilterContext context)
{
var configService = (IConfiguration)context.HttpContext.RequestServices.GetService(typeof(IConfiguration));
if (configService != null)
{
var enableAuth = configService.GetValue<bool>("AppSettings:EnableAuthentication");
if (enableAuth)
{
if (user?.Identity?.IsAuthenticated != true)
{
context.Result = new UnauthorizedResult();
}
}
}
else
{
context.Result = new UnauthorizedResult();
}
}
}
当我使用单一身份验证方案时,这就像一个魅力。当我使用两个方案时,它适用于默认方案('Bearer',但不是我的第二个方案)。查看日志,我看到了这个
2021-07-19 14:50:41.616 +02:00 [信息] Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:失败 验证令牌。 Microsoft.IdentityModel.Tokens.SecurityTokenUnableToValidateException: IDX10516:签名验证失败。无法匹配键:
现在,据我了解,当第一个 jwt 方案无法验证令牌时这是正常的。第二个可以。但是,在我的OptionalAuthorizationAttribute context.HttpContext.User.Identity 现在是未经身份验证的,所以请求仍然被拒绝。我猜User.Identity 正在通过默认方案后从令牌中获取的内容填充(无法验证令牌,因此它是一个空的ClaimsIdentity 并且未经授权。
我是否有机会从第二个身份验证方案中获取身份? (并使其通用,以防我需要添加其他身份验证方案)。
如果我换掉控制器上的[OptionalAuthorization] 标签并用[Authorize] 替换它,一切都会正常工作,所以我知道我的设置已完成.. 只是在验证令牌之前我的属性被触发使用第二种方案。
这是一个控制器,显示我如何使用我的OptionalAuthorizationAttribute
[Route("[controller]")]
[ApiController]
public class WebDirectoryController:ControllerBase
{
[HttpGet]
[OptionalAuthorization]
[Route("Sources")]
public IActionResult GetPlugins()
{
... implementation
}
}
【问题讨论】:
-
您能分享您的控制器代码吗?您是否为整个控制器启用了[Authorize]?
-
我添加了一个示例控制器。该示例显示了不工作的情况(当令牌用于第一个身份验证方案时,它工作,第二个它不工作)。如果我将
[OptionalAuthorization]替换为[Authorize]它适用于两种身份验证方案(但我不再可以选择通过AppSettings:EnableAuthentication关闭授权)
标签: c# jwt authorization asp.net-core-3.1