Атрибут Authorize
сам по себе служит только для указания вида авторизации, который вам необходим на определенной странице или контроллере.Этот атрибут предназначен для использования в дополнение к платформе Identity и может включать роли, политики и схемы аутентификации.
Вам нужно создать мост между платформой Identity и вашей базой данных, что можно сделать с помощью пользовательских UserStore
и RoleStore
, что подробно описано на этой странице .
Подводя итог довольно сложному процессу:
- Атрибут
Authorize
указывает браузеру аутентифицировать вашего пользователя - Ваш пользователь перенаправлен на страницу аутентификации
- Если это удастся, вам предоставляется экземпляр
ClaimsPrincipal
, который затем необходимо сопоставить с пользователем вашей базы данных с помощью пользовательского UserStore
- . Затем ваш пользователь может проверитьРоли в БД
Вот краткий пример всего этого в действии (НЕ полностью завершенного, потому что это будет слишком много кода).
Startup.cs
// This class is what allows you to use [Authorize(Roles="Role")] and check the roles with the custom logic implemented in the user store (by default, roles are checked against the ClaimsPrincipal roles claims)
public class CustomRoleChecker : AuthorizationHandler<RolesAuthorizationRequirement>
{
private readonly UserManager<User> _userManager;
public CustomRoleChecker(UserManager<User> userManager)
{
_userManager = userManager;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement)
{
var user = await _userManager.GetUserAsync(context.User);
// for simplicity, I use only one role at a time in the attribute
var singleRole = requirement.AllowedRoles.Single();
if (await _userManager.IsInRoleAsync(user, singleRole))
context.Succeed(requirement);
}
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddIdentity<User, Role>()
.AddUserStore<MyUserStore>()
.AddRoleStore<MyRoleStore>();
// custom role checks, to check the roles in DB
services.AddScoped<IAuthorizationHandler, CustomRoleChecker>();
}
, где User
и Role
- ваши основные объекты EF.
MyUserStore
public class MyUserStore : IUserStore<User>, IUserRoleStore<User>, IQueryableUserStore<User>
{
private Context _db;
private RoleManager<Role> _roleManager;
...
public async Task<User> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
{
// bridge your ClaimsPrincipal to your DB users
var user = db.Users.SingleOrDefault(_ => _.Email.ToUpper() == normalizedUserName);
return await Task.FromResult(user);
}
...
public async Task<bool> IsInRoleAsync(User user, string roleName, CancellationToken cancellationToken)
{
if (roleName == null)
return true;
// your custom logic to check role in DB
var result = user.Roles.Any(_ => _.RoleName == roleName);
return await Task.FromResult(result);
}