我喜欢asp.net身份使您可以通过仅在控制器方法顶部添加注释来巧妙地管理基于角色的授权的方式。但是,如果您不使用实体框架怎么办?如果将ADO.NET与ASP.NET Core API一起使用怎么办?您如何管理基于角色的授权?
[Authorize(Roles = Role.Admin)]
[HttpGet]
public IActionResult GetAll()
{
var users = _userService.GetAll();
return Ok(users);
}
也许我们可以通过创建ActionFilter并检查拥有用户角色的全局变量的值是什么来模仿这一点?我有什么选择?
这是基于策略的授权的一个很好的例子。您将使用自定义的IAuthorizationHandler
和IAuthorizationRequirement
。请参阅此处的文档:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-3.0
我最近在一个项目中做到了这一点。您可以创建命名策略,例如“ Admin”。您的AuthorizationHandler
将访问当前用户身份,并可以通过将服务注入处理程序来查找其当前角色。然后,用[Authorize(Policy = "Admin")]
装饰控制器/动作。
在我的项目中,我的AuthorizationHandler
和AuthorizationRequirement
看起来像这样:
public class CreateClientHandler : AuthorizationHandler<CreateClientRequirement, CreateClientRequest>, IAuthorizationRequirement
{
private readonly IStudioService _studioService;
public CreateClientHandler(
IStudioService studioService
)
{
_studioService = studioService;
}
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
CreateClientRequirement requirement,
CreateClientRequest resource
)
{
var userIdClaim = context.User.Claims.SingleOrDefault(c => c.Type == ClaimTypes.Name);
if (userIdClaim == null)
{
context.Fail();
return Task.CompletedTask;
}
if (resource != null)
{
var userId = int.Parse(userIdClaim.Value);
if (!UserIsAdmin(userId))
{
context.Fail();
return Task.CompletedTask;
}
}
context.Succeed(requirement);
return Task.CompletedTask;
}
}
public class CreateClientRequirement : IAuthorizationRequirement {}
在我的ConfigureServices
中,在Startup.cs
中:
services.AddAuthorization(options =>
{
options.AddPolicy("CreateClient", policy =>
policy.Requirements.Add(new CreateClientRequirement()));
});
一旦完成所有配置,我就可以用[Authorize(Policy = "CreateClient")]
装饰控制器动作。
我在Asp.Net MVC中创建了一个小项目。您可以使用此仓库创建您的Asp.Net Core项目
这里:https://github.com/harmathdavid/EnumAuthorization
快乐编码! :)