Asp.net core 在JWT授权中,检查用户是否具有角色Admin

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

我正在开发一个.Net核心API,在我的控制器中,我有以下代码:

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没有问题,很高兴它帮助了你:)