我在ApiUser和CompanyBased两个地方制定了策略。当我使用基于公司的策略时([Authorize(Policy =“ CompanyBased”)] ),应用程序无法验证JWT令牌。当我使用[授权]时,效果很好,令牌已通过验证...
版本:核心2.2
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService [2] 授权失败。 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [3] 筛选器“ Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter”上的请求授权失败。 Microsoft.AspNetCore.Mvc.ForbidResult [1] 使用身份验证方案()执行ForbidResult。 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler [13] AuthenticationScheme:禁止承载。
// api user claim policy
services.AddAuthorization(options =>
{
options.AddPolicy("ApiUser", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, Constants.Strings.JwtClaims.ApiAccess));
options.AddPolicy("CompanyBased", policy =>
{
policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, Constants.Strings.JwtClaims.ApiAccess);
policy.AddRequirements(new CompanyBasedRequirement());
});
});
这是CompanyBasedHandler
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CompanyBasedRequirement requirement)
{
#region Validate Company id
Guid? companyId = _httpContextAccessor.HttpContext.Request.Headers.GetCompanyId();
string nameIdentifier = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
if (companyId is null)
{
_logger.LogInformation($"No company suppied for {nameIdentifier}");
context.Fail();
}
else
{
if (!_clientRepository.IsClientValid(companyId.Value, nameIdentifier))
{
_logger.LogInformation($"{companyId} does not belong to {nameIdentifier}");
context.Fail();
}
else
{
context.Succeed(requirement);
}
}
#endregion Validate Company id
return Task.CompletedTask;
}
先谢谢!
答案 0 :(得分:1)
确保在Startup类的依赖项注入容器中正确注册了自定义授权处理程序。它应该注册为单例:
services.AddSingleton<IAuthorizationHandler, CompanyBasedHandler>();
您可以通过将方法签名更改为HandleRequirementAsync
来使async Task
异步/等待,然后在方法末尾不返回完成的Task,例如:
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CompanyBasedRequirement requirement)
{
#region Validate Company id
Guid? companyId = _httpContextAccessor.HttpContext.Request.Headers.GetCompanyId();
string nameIdentifier = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
if (companyId is null)
{
_logger.LogInformation($"No company suppied for {nameIdentifier}");
context.Fail();
}
else
{
if (!_clientRepository.IsClientValid(companyId.Value, nameIdentifier))
{
_logger.LogInformation($"{companyId} does not belong to {nameIdentifier}");
context.Fail();
}
else
{
context.Succeed(requirement);
}
}
#endregion Validate Company id
}
请注意,您没有在该方法中执行任何异步操作,这意味着它将同步运行,因此无需使此方法异步。
答案 1 :(得分:0)
我在令牌中缺少Constants.Strings.JwtClaimIdentifiers.Rol!