ASP.NET Core 引入了可应用于 Authorize 属性的策略概念。像过滤器一样工作,但不编写过滤器。
每项政策都必须满足一项或多项要求,政策才能通过。 Microsoft docs 有一个设置策略的好例子。在您的情况下,我会执行以下操作:
首先,从“需求”开始
public class TeamAccessRequirement : IAuthorizationRequirement
{
}
然后添加一个需求处理程序
public class TeamAccessHandler : AuthorizationHandler<TeamAccessRequirement>
{
private readonly DbContext dbContext;
public TeamAccessHandler(DbContext dbContext)
{
// example of an injected service. Put what you need here.
this.dbContext = dbContext;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TeamAccessRequirement requirement)
{
// pattern matching is cool. if you can't do this, use context.Resource as AuthorizationFilterContext before and check for not null
if (context.Resource is AuthorizationFilterContext authContext)
{
// you can grab the team id, (but no model builder to help you, sorry)
var teamId = Guid.Parse(authContext.RouteData.Values["teamId"]);
// now you can do the code you would have done in the guts of the actions.
if (context.User.IsTeamAdmin(teamId))
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
}
return Task.CompletedTask;
}
}
然后,你需要把所有这些放在一起,并在ConfigureServices下的Startup.cs中启用它,像这样:
services.AddAuthorization(options =>
{
options.AddPolicy("HasAdminTeamAccess", policy =>
policy.Requirements.Add(new TeamAccessRequirement()));
});
services.AddTransient<IAuthorizationHandler, TeamAccessHandler>();
最后是用法:
[HttpGet]
[Authorize(Policy = "HasAdminTeamAccess")]
public IActionResult ManageTeam(Guid teamId)
{ }
现在您的行为仍然干净整洁。在这里,您可以通过将功能添加到您可以从处理程序调用的需求中来微调策略,或者做任何您想做的事情。