c# - 使用 JWT 的 aspcore 多策略
问题描述
我有两项政策,即 ApiUser 和 CompanyBased。当我使用基于公司的策略 ([Authorize(Policy = "CompanyBased")] ) 时,应用程序无法验证 JWT 令牌。当我使用 [Authorize] 时,它运行良好,令牌得到验证......
版本:核心 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;
}
- 如何确保 CompanyBased 验证 JWT 令牌
- 我可以用 await 使 HandleRequirementAsync 异步吗,我被 return await Task.CompletedTask 卡住了(这不起作用)!
解决方案
确保您在 Startup 类的依赖注入容器中正确注册了自定义授权处理程序。它应该注册为单例:
services.AddSingleton<IAuthorizationHandler, CompanyBasedHandler>();
您可以HandleRequirementAsync
通过将方法签名更改为async 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
}
请注意,您没有在方法中执行任何异步操作,这意味着它将同步运行,因此不需要使此方法异步。
推荐阅读
- r - 当有多个重复时,如何在 R 中选择数据框的行?
- sql - 这个sql复杂的面试题的解决方法是什么?
- python - Python Backtrader 错误:FileNotFoundError:[Errno 2] 没有这样的文件或目录:'AAPL'
- javascript - 页面加载时 Vue.js 中元素的随机/随机顺序
- php - 如何在 laravel 的 Seeder 中为用户分配角色
- sql-server - JSON_VALUE 以方括号结尾的 JSON 对象
- javascript - 与来自 api rest 的数据反应时渲染图形时出错
- python - 使用一个变量读取两个文件?
- node.js - 无效构建:无效图像名称“gcr.io/sam-api-267023/https://sam-api-267023.appspot.com/:a83bcce15e7329d9925cda40a17a9f588afe478f”
- python - 有没有办法将 pandas .isin() 函数与多个列表一起使用?