角色的权限在住宿角色转变

问题描述:

时,我有一个ASP.NET MVC的核心部位使用ASP.NET核心授权这样一个SQLite数据连接:角色的权限在住宿角色转变

// 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
  • 用户A使用Index()作用Editor - 仍然成功

您会期望用户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<>再次登录的用户,但它好像你只能注销当前用户 - 这将成为用户改变角色而不是角色将被改变的用户。


我错过了什么?如果用户不需要做任何事情(例如重新登录)以便“刷新”用户角色,那将会很好。

+0

您使用的是cookie认证吗? – Brad

问题是用户的角色声明存储在cookie(aspnet标识的默认实现)中,因此,除非用户注销,即使用户角色更改,授权结果也不会更改。解决方案是使用ValidateAsync事件。 Example存在于官方文档中。

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

为此,您需要覆盖CreateAsync方法UserClaimsPrincipalFactory请参阅article如何更改索赔。然后你可以使用claims transformation添加角色声明。