Ответ 1
На основе комментариев здесь приведен пример использования авторизации на основе политик:
public class PermissionRequirement : IAuthorizationRequirement
{
public PermissionRequirement(PermissionEnum permission)
{
Permission = permission;
}
public PermissionEnum Permission { get; }
}
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
private readonly IUserPermissionsRepository permissionRepository;
public PermissionHandler(IUserPermissionsRepository permissionRepository)
{
if(permissionRepository == null)
throw new ArgumentNullException(nameof(permissionRepository));
this.permissionRepository = permissionRepository;
}
protected override void Handle(AuthorizationContext context, PermissionRequirement requirement)
{
if(context.User == null)
{
// no user authorizedd. Alternatively call context.Fail() to ensure a failure
// as another handler for this requirement may succeed
return null;
}
bool hasPermission = permissionRepository.CheckPermissionForUser(context.User, requirement.Permission);
if (hasPermission)
{
context.Succeed(requirement);
}
}
}
И зарегистрируйте его в своем классе Startup
:
services.AddAuthorization(options =>
{
UserDbContext context = ...;
foreach(var permission in context.Permissions)
{
// assuming .Permission is enum
options.AddPolicy(permission.Permission.ToString(),
policy => policy.Requirements.Add(new PermissionRequirement(permission.Permission)));
}
});
// Register it as scope, because it uses Repository that probably uses dbcontext
services.AddScope<IAuthorizationHandler, PermissionHandler>();
И, наконец, в контроллере
[HttpGet]
[Authorize(Policy = PermissionEnum.PERSON_LIST.ToString())]
public ActionResult Index(PersonListQuery query)
{
...
}
Преимущество этого решения заключается в том, что вы также можете иметь несколько обработчиков для требования, т.е. если первым удастся, второй обработчик может определить его сбой, и вы можете использовать его с ресурсная авторизация с небольшими дополнительными усилиями.
Политический подход - это предпочтительный способ сделать это командой ASP.NET Core.
Из blowdart:
Мы не хотим, чтобы вы писали пользовательские атрибуты авторизации. Если вам нужно это сделать, мы сделали что-то не так. Вместо этого вы должны писать требования авторизации.