【发布时间】:2017-10-25 20:51:35
【问题描述】:
我刚刚开始使用 ASP.NET Core Identity 并定义了以下要求:
public sealed class IsCustomerUserRequirement : IAuthorizationRequirement
public sealed class IsSuperUserRequirement : IAuthorizationRequirement
使用以下基本处理程序:
public class IsCustomerUserHandler : AuthorizationHandler<IsCustomerUserRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsCustomerUserRequirement requirement)
{
if (context.User.HasClaim(_ => _.Type == "customer"))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
public class IsSuperUserHandler : AuthorizationHandler<IsSuperUserRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsSuperUserRequirement requirement)
{
if (context.User.IsInRole("super_user"))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
然后我可以将这些放在基本政策中:
services
.AddAuthorization(options =>
{
options.AddPolicy("MustBeSuperUser", policy => policy.Requirements.Add(new IsSuperUserRequirement()));
options.AddPolicy("CustomersOnly", policy => policy.Requirements.Add(new IsCustomerUserRequirement()));
});
并使用[Authorize("CustomersOnly")] 应用它,效果很好。
我的要求是能够允许超级用户声明具有super_user 角色但没有 customer 声明的主体,也可以访问仅限客户的区域。
我目前已通过将处理程序更改为手动检查来实现这一点:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsCustomerUserRequirement requirement)
{
if (context.User.HasClaim(_ => _.Type == Claims.Customer) ||
context.User.IsInRole(Roles.SuperUser))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
我的问题感觉好像我没有抓住重点。有没有更好的方法来定义这个,所以我以后不必在每个处理程序中重复超级用户检查?
这一切的大局是我使用 IdentityServer4 (ASP.NET Identity-backed) 进行身份验证,然后打算使用一些基于 JWT 的声明(一个声明,两个角色)来进一步识别用户授权属于特定于应用程序角色/权限结构和一些与 Identity Server 无关的自定义中间件。围绕该主题有哪些最佳实践(如果有)?
【问题讨论】:
-
我发现在 netcore 中基于策略的新授权方式在进行细粒度授权时有点不友好。我们最终实现了一个自定义操作过滤器(继承
IAsyncActionFilter)来处理授权,并且比使用那些需要在启动时设置的策略提供更多的灵活性。由于用户拥有的声明的简单变化,人们不希望拥有相同策略的 X 个变体。 -
@scheien 如果同一策略有多个变体,则说明您使用的策略和要求不正确。一个策略应该需要一组要求。这些要求可以(单独地)通过各种索赔组合来满足,然后由需求处理程序来解决。但这不会使政策更加复杂。 – 随意发布一个问题,概述您的具体情况,我也许可以帮助您简化它以适应新模型。 ASP.NET Core 身份验证堆栈实际上非常干净且功能强大。