如果我有管理员政策,请添加其他政策

时间:2019-07-12 10:36:00

标签: c# asp.net-core authorization policies

我有一个具有authorize属性的控制器:

Authorize(AuthorizationPolicies.Viewer)]
[HttpGet("retrieve/{id}")]
public ActionResult<ISomeInterface> Retrieve(int id)

并具有授权政策:

public static void AddViewerPolicy(AuthorizationOptions options)
{
    options.AddPolicy(AuthorizationPolicies.Viewer, p => BuildPolicy(p, Permissions.Viewer));
}

public static void AddAdminPolicy(AuthorizationOptions options)
{
    options.AddPolicy(AuthorizationPolicies.Admin, p => BuildPolicy(p, Permissions.Admin));
}

如果我具有“管理员”策略,则需要访问标有“查看器”授权策略的控制器。

我已经尝试过了:

public static void AddAdminPolicy(AuthorizationOptions options)
{
    options.AddPolicy(AuthorizationPolicies.Admin, p => BuildPolicy(p, Permissions.Admin));

    options.AddPolicy(AuthorizationPolicies.Viewer, p => BuildPolicy(p, Permissions.Viewer));
}

这里是BuildPolicy

private static void BuildPolicy(AuthorizationPolicyBuilder policy, int permission)
{
    policy.AddAuthenticationSchemes(Defaults.SchemeName); 
    policy.AddRequirements(new AuthorizationRequirement
    {
        Require = Access.Always,
        PermissionsRequired = new[] { permission }
    });
}

    public class AuthorizationHandler
  {
    protected override Task HandleRequirementAsync(
      AuthorizationHandlerContext context,
      AuthorizationRequirement requirement)
    {
      ClaimsPrincipal user = context.User;
      if (user == null)
      {
        context.Fail();
        return Task.CompletedTask;
      }
      Identity Identity = user.Identities.OfType<Identity>().FirstOrDefault<Identity>();

      if (requirement.PermissionsRequired != null && ((IEnumerable<int>) requirement.PermissionsRequired).Any<int>())
      {
        if (requirement.Require != Access.Always)
        {
          context.Fail();
          return Task.CompletedTask;
        }
        Client client;
        if (!user.TryGetClient(out client))
        {
          context.Fail();
          return Task.CompletedTask;
        }
        if (client.Permissions == null)
        {
          context.Fail();
          return Task.CompletedTask;
        }
        if (!((IEnumerable<int>) requirement.PermissionsRequired).Any<int>((Func<int, bool>) (rap => client.Permissions.Contains(rap))))
        {
          context.Fail();
          return Task.CompletedTask;
        }
      }
      if (requirement.AllowImpersonatedUser && Identity.Client != null && Identity.IsImpersonated)
      {
    context.Succeed((IAuthorizationRequirement) requirement);
    return Task.CompletedTask;
      }
      context.Fail();
      return Task.CompletedTask;
    }
  }

但是结果是403错误。那么您可能还有另一个更好的主意吗?

1 个答案:

答案 0 :(得分:0)

您不是尝试添加两个都有一个权限ID的策略,而是尝试将一个带有两个权限ID的策略添加为一个数组?

public static void AddAdminPolicy(AuthorizationOptions options)
{
    options.AddPolicy(AuthorizationPolicies.Admin, p => BuildPolicy(p, new [] { Permissions.Admin, Permissions.Viewer }));
}

private static void BuildPolicy(AuthorizationPolicyBuilder policy, int[] permissions)
{
    policy.AddAuthenticationSchemes(Defaults.SchemeName); 
    policy.AddRequirements(new AuthorizationRequirement
    {
        Require = Access.Always,
        PermissionsRequired = permissions
    });
}