JWT的aspcore多策略

时间:2019-01-08 02:03:07

标签: c# asp.net-core

我在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;
}
  1. 如何确保CompanyBased验证JWT令牌
  2. 我可以使HandleRequirementAsync与await保持异步吗,我被困在return await Task.CompletedTask(不起作用)中!

先谢谢!

2 个答案:

答案 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!