Esta é uma pergunta complicada e não há uma resposta certa, mas existem várias maneiras de fazê-lo. Primeiro, assumirei que você está usando autenticação sem estado usando uma declaração baseada em declarações. A maneira mais simples é escrever sua própria política que lerá as funções de usuário antes de cada solicitação; essa é a maneira mais simples de fazer isso e a implementação mais rápida.
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);
}
}
}
Mas essa solução não tem esse desempenho porque requer uma chamada ao banco de dados em cada solicitação. Isso é bom em pequenas cargas, mas pode criar problemas no tráfego. A outra maneira é reavivar todos os tokens de usuário quando as funções mudam, mas isso é super complicado. Tenho certeza de que, se você criar algum armazenamento de acesso rápido para funções como redis, não haverá problemas para verificar todas as chamadas. Também não recomendo criar seu próprio armazenamento de usuário, pois é um pesadelo manter e manter-se atualizado em relação aos padrões de segurança.
Authorize(Roles ="Staff")
garante que o usuário com funçãoStaff
somente possa acessar esta ação ... Portanto, se o usuário for removido dessa função, o usuário não poderá acessar isso. Isso não está acontecendo?