我正在创建一个应用程序,其中包含基于角色的模块管理,并且可以随时对其进行更改。 场景:
- 如果用户有权创建和查看员工,则该用户只能创建和查看员工,但在将来的管理员中,将用户的角色从创建,查看,查看和删除更改为用户只能执行该活动。
我尝试使用[Authorize(Roles ="Staff")]
,但是如果管理员更改了运行时,则无法对其进行管理。
任何人都可以调查一下并回到我身边吗?
我正在创建一个应用程序,其中包含基于角色的模块管理,并且可以随时对其进行更改。 场景:
我尝试使用[Authorize(Roles ="Staff")]
,但是如果管理员更改了运行时,则无法对其进行管理。
任何人都可以调查一下并回到我身边吗?
这是一个复杂的问题,没有正确的答案,但是有几种方法可以解决。 首先,我假设您正在使用基于声明的jwt的无状态身份验证,最简单的方法是编写自己的Policy,它将在每个请求之前读取用户角色,这是最简单的方法,也是实现最快的方法。
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这样的角色创建一些快速访问存储,那么在每个呼叫上进行检查都不会有问题。另外,我也不建议您创建自己的用户存储,因为这是维护和保持最新安全标准的噩梦。
,如果您使用Session / Cookie存储登录的用户详细信息,则每当管理员更改角色时都可以清空这些详细信息。在每个操作上,您都可以检查Session / Cookie中的角色并继续前进。 现在,只要用户在屏幕上的任何位置单击即可点击控制器。会话/ Cookie对象为空,将检查条件并注销用户。