2016-09-13 52 views
0

時,我有一個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

回答

1

問題是用戶的角色聲明存儲在cookie(aspnet標識的默認實現)中,因此,除非用戶註銷,即使用戶角色更改,授權結果也不會更改。解決方案是使用ValidateAsync事件。 Example存在於官方文檔中。

另一個可能的解決方案是從cookie中排除角色聲明並使用聲明轉換。

爲此,您需要覆蓋CreateAsync方法UserClaimsPrincipalFactory請參閱article如何更改索賠。然後你可以使用claims transformation添加角色聲明。