2017-08-15 33 views
0

我在一個.net核心API的工作,和我的控制器裏面,我有以下代碼:在智威湯遜的授權,檢查用戶是否具有角色admin

if (User.Identity.IsAuthenticated) 
{ 
    var username = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier); 
    var user = await _userManager.FindByNameAsync(username); 
    artistCardDtoCollection = _artistsService.GetAllArtists(user.Id, User.IsInRole("Admin")); 
} 

上面的代碼,是因爲我希望傳遞User.Id(如果已登錄)和IsAdmin標誌與我的GetAllArtists方法相關。

上面的代碼在User.IsInRole("Admin")上失敗。當我100%知道所涉及的用戶是Admin時,我得到一個false。我已經雙重檢查數據庫通過SQL Management Studio。

這讓我覺得在使用智威湯遜時不能使用User.IsInRole()。如果是這樣的話,那麼正確的方法是什麼?由於

回答

1

也許這可能是緩存的問題與User.IsInRole(),如果我們檢查documentation我們會發現:

IsInRole 第一檢查IsRoleListCached屬性來確定 是否角色名稱的緩存列表當前用戶可用。 如果IsRoleListCached屬性爲true,則爲指定角色檢查緩存列表 。如果IsInRole方法在高速緩存列表中找到指定的 角色,則它將返回true。如果IsInRole找不到 指定的角色,則它會調用默認的 提供程序實例的GetRolesForUser方法,以確定用戶名是否與來自數據源的角色關聯的 與配置的ApplicationName 值關聯。

在你的情況,你可以嘗試使用GetRolesAsync象下面這樣:

var user = await _userManager.FindByNameAsync(username); 
var roles = await _userManager.GetRolesAsync(user); 
artistCardDtoCollection = _artistsService.GetAllArtists(user.Id, roles.Contains("Admin")); 
+0

既能'_userManager.FindByNameAsync(用戶名);'和'_userManager.GetRolesAsync(用戶);'撥打電話到數據庫?所以兩個電話給Db。如果我停止並啓動應用程序,緩存也不會被清除嗎? – Ciwan

+0

您的代碼有效。 IsAdmin標誌現在被設置爲true。 – Ciwan

+1

@Ciwan是的,2個查詢。爲了通過1個查詢獲得角色名稱,我們應該創建2個連接,第一個獲取角色,第二個連接獲取角色名稱。在這裏,我們有一個簡單的查詢用戶和1與1 RoleName,所以它應該幾乎相同的時間(我測量它)。 'GetRolesAsync'生成下一個SQL:'SELECT [role]。[Name] FROM [AspNetUserRoles] AS [userRole] INNER JOIN [AspNetRoles] AS [role] ON [userRole]。[RoleId] = [role]。[Id ] WHERE [userRole]。[UserId] = @ userId',所以你只需傳入'new ApplicationUser {id = userid}'而不是整個User對象,它對我來說工作得很好。 – user2771704