Asp.net core 在JWT授权中,检查用户是否具有角色Admin
我正在开发一个.Net核心API,在我的控制器中,我有以下代码:Asp.net core 在JWT授权中,检查用户是否具有角色Admin,asp.net-core,jwt,Asp.net Core,Jwt,我正在开发一个.Net核心API,在我的控制器中,我有以下代码: if (User.Identity.IsAuthenticated) { var username = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier); var user = await _userManager.FindByNameAsync(username); artistCardDtoCollection = _artistsSe
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%地知道所讨论的用户是管理员时,我得到一个false
。我已经通过SQL Management Studio仔细检查了数据库
这让我觉得在使用JWT时不能使用
User.IsInRole()
。如果是这样,那么正确的方法是什么?谢谢如果我们检查,可能是由于User.IsInRole()
的缓存问题造成的,我们会发现:
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"));
可能是由于
User.IsInRole()
的缓存问题,如果我们进行检查,会发现:
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"));
将两者都
\u userManager.FindByNameAsync(用户名)
和\u userManager.GetRolesAsync(用户)代码>调用数据库?因此,对数据库进行了两次调用。如果我停止并启动应用程序,缓存不会被清除吗?你的代码可以工作。IsAdmin
标志现在被设置为true。@Ciwan是,2个查询。为了通过1次查询获得角色名,我们应该进行2次连接,第一次是通过id获取角色名,第二次是通过id获取角色名。在这里,我们为用户进行了1次简单查询,为RoleName进行了1次连接,所以时间应该几乎相同(我测量了它)GetRolesAsync
生成下一个SQL:从[AspNetUserRoles]中选择[role].[Name]作为[userRole]内部连接[AspNetRoles]作为[userRole].[RoleId]=[role].[Id]其中[userRole].[UserId]=@UserId
,这样你就可以用Id传递新的ApplicationUser{Id=UserId}
,不是整个用户对象,它对我很好。@Ciwan没有问题,很高兴它帮助了你:)将同时\u userManager.FindByNameAsync(用户名)
和\u userManager.GetRolesAsync(用户)代码>调用数据库?因此,对数据库进行了两次调用。如果我停止并启动应用程序,缓存不会被清除吗?你的代码可以工作。IsAdmin
标志现在被设置为true。@Ciwan是,2个查询。为了通过1次查询获得角色名,我们应该进行2次连接,第一次是通过id获取角色名,第二次是通过id获取角色名。在这里,我们为用户进行了1次简单查询,为RoleName进行了1次连接,所以时间应该几乎相同(我测量了它)GetRolesAsync
生成下一个SQL:从[AspNetUserRoles]中选择[role].[Name]作为[userRole]内部连接[AspNetRoles]作为[userRole].[RoleId]=[role].[Id]其中[userRole].[UserId]=@UserId
,这样你就可以用Id传递新的ApplicationUser{Id=UserId}
,不是整个用户对象,它对我很好。@Ciwan没有问题,很高兴它帮助了你:)