Это сложный вопрос, и нет правильного ответа, но есть несколько способов сделать это. Сначала я буду предполагать, что вы используете аутентификацию без сохранения состояния с использованием jwt на основе утверждений. Самый простой способ - написать собственную Политику , которая будет читать роли пользователей перед каждым запросом, это самый простой способ сделать это и быстрее всего реализовать.
internal class DatabaseRoles : IAuthorizationRequirement
{
public string Role { get; }
public DatabaseRoles(string role)
{
Role = role;
}
}
internal class DatabaseRolesHandler : AuthorizationHandler<DatabaseRoles>
{
private readonly UserManager<IdentityUser> userManager;
public DatabaseRolesHandler(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager)
{
this.userManager = userManager;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, DatabaseRoles requirement)
{
//NOTE this is the out of the box implementation of roles and simple query to get the roles from the EF backed database. I would recoment makeing a custom privelages store for this and not using roles for this but access rights
var user = await userManager.FindByIdAsync(userManager.GetUserId(context.User));
if (await userManager.IsInRoleAsync(user, requirement.Role))
{
context.Succeed(requirement);
}
}
}
Но это решение не так эффективно, потому что оно требует обращения к базе данных при каждом запросе. Это хорошо для небольших нагрузок, но может создать проблемы в движении. Другой способ - повторно вызывать все пользовательские токены при смене ролей, но это очень сложно. Я уверен, что если вы создадите хранилище быстрого доступа для таких ролей, как redis, проблем с проверкой каждого вызова не возникнет. Также я не рекомендую создавать свое собственное хранилище для пользователей, потому что это кошмар, который нужно поддерживать и постоянно обновлять в соответствии со стандартами безопасности.