角色权限'改变角色时留下来

时间:2016-09-13 19:55:06

标签: c# asp.net-core authorization

我有一个使用ASP.NET核心授权的SQLite数据连接的ASP.NET核心MVC站点,如下所示:

// Startup.ConfigureServices
services.AddAuthorization(e =>
{
    e.AddPolicy(Policies.UserRead, b => b.RequireRole("Editor", "Root"));
}

这是限制使用用户信息访问网站的政策之一。 (Policies.UserRead是常量string)。然后将此策略应用于此视图:

[Authorize(Policies.UserRead)]
public async Task<IActionResult> Index()
{
}

效果很好,只有角色为EditorRoot的用户才能访问该视图。但是当登录时改变用户的角色时会出现问题。例如

  • 用户A(角色Editor)登录并使用Index() - 成功
  • 用户B(角色Root)登录并从用户A中删除角色Editor
  • 用户A使用Index() - 仍然成功

您可能希望用户A不再访问Index(),因为他不再是Editor角色。 Buuuut他仍然可以 - 只要他不退出并重新登录,因为重新解决修复了这个问题。似乎有人(我认为ClaimsPrincipal是罪魁祸首)缓存了角色 - 如果我知道如何使缓存失效,那将是OK ...

角色转换代码:

// get the user whos role is changed
var targetUser = await _context.Users.SingleOrDefaultAsync(m => m.Id == model.Id);
if (targetUser == null) return NotFound();

// get the user who changes the role
var sourceUser = await _userManager.GetUserAsync(User);
if (sourceUser == null) return RedirectToAction("Index");

// remove the current role
await _userManager.RemoveFromRoleAsync(targetUser, targetUser.Role.ToString());

// add to the new role
await _userManager.AddToRoleAsync(targetUser, model.Role.ToString());

// update & save the changes
_context.Update(targetUser);
await _context.SaveChangesAsync();

这基本上是我用来改变用户角色的代码(我剪掉了视图/模型部分因为它们无关紧要)。注意:

  • targetUsersourceUser都是ApplicationUser(实现IdentityUser)。

  • _userManger - 谁会想到 - 类型UserManager<ApplicationManger>

我尝试使用SignInManger<>重新启动用户,但似乎您只能注销当前用户 - 即更改角色的用户,而不是更改角色的用户。

我错过了什么?如果用户不必做任何事情(例如重新登录)以便&#34;刷新&#34; 用户角色,那就太好了。

1 个答案:

答案 0 :(得分:1)

问题是用户的角色声明存储在cookie中(aspnet身份的默认实现),因此即使用户的角色发生变化,除非用户退出,否则授权结果不会改变。解决方案是使用ValidateAsync事件。 Example存在于官方文档中。

另一种可能的解决方案是从cookie中排除角色声明并使用声明转换。

为此,您需要覆盖CreateAsync的{​​{1}}方法,请参阅此article如何更改声明。然后,您可以使用claims transformation添加角色声明。