【发布时间】:2018-08-22 06:57:04
【问题描述】:
我想为控制器上的所有操作要求一个策略,并且我还想为所有对 HTTP“编辑方法”(POST、PUT、PATCH 和 DELETE)的调用要求另一个策略。也就是说,编辑方法应该需要这两种策略。由于实现要求,以及保持代码 DRY 的愿望,我需要在控制器级别应用后一种策略,而不是在所有操作方法上重复。
举个简单的例子,我有一个PeopleController,我也有两个权限,实现为策略,ViewPeople 和EditPeople。现在我有:
[Authorize("ViewPeople")]
public class PeopleController : Controller { }
如何添加 EditPeople 策略/权限,使其“堆叠”并仅适用于编辑动词?
我遇到了两个似乎都很痛苦的问题:
- 在 AuthorizeAttribute、AFAIK 中不能有多个 AuthorizeAttribute 或多个 Policy。
- 在自定义的AuthorizationHandler中无法访问Request,所以无法查看HttpMethod来查看。
我尝试使用自定义 Requirement 和 AuthorizationHandler 解决前者,如下所示:
public class ViewEditRolesRequirement : IAuthorizationRequirement
{
public ViewEditRolesRequirement(Roles[] editRoles, Roles[] viewRoles)
=> (EditRoles, ViewRoles) = (editRoles, viewRoles);
public Roles[] EditRoles { get; }
public Roles[] ViewRoles { get; }
}
public class ViewEditRolesHandler : AuthorizationHandler<ViewEditRolesRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ViewEditRolesRequirement requirement)
{
if (context.User != null)
{
var canView = requirement.ViewRoles.Any(r => context.User.IsInRole(r.ToString()));
var canEdit = requirement.EditRoles.Any(r => context.User.IsInRole(r.ToString()));
if (context. // Wait, why can't I get to the bloody HttpRequest??
}
return Task.CompletedTask;
}
}
...但在我意识到我无权访问请求对象之前,我已经达到了if (context.。
我唯一的选择是覆盖控制器中的OnActionExecuting 方法并在那里进行授权吗?我想这至少是不被接受的?
【问题讨论】:
标签: c# asp.net-core asp.net-core-identity asp.net-authorization