如何在 ASP.NET Core Identity 中使用角色 GUID 而不是名称?
How can I use role GUIDs instead of names in ASP.NET Core Identity?
我一直在使用一些示例在 ASP.NET Core 中使用 Identity,但有些事情让我很沮丧。即使角色模型有一个主键 Id
和一个字符串 Name
,它也是由各种内置服务传递的名称。
例如,当我调用 _userManager.GetRolesAsync(user)
时,我得到了一个字符串名称列表。如果我想要身份证怎么办?这个没有 API 所以我必须使用角色管理器来获取所有角色并映射它们。默认情况下,角色名称不受唯一键的限制,因此这是不可靠的。
我一定是漏掉了什么,但是什么?我现在的用例是我想用用户的角色填充 JWT 声明。就我而言,角色名称是我的应用程序内部的,我不想将它们公开给客户。
对于_userManager.GetRolesAsync(user)
,它调用userRoleStore.GetRolesAsync
public virtual async Task<IList<string>> GetRolesAsync(TUser user)
{
ThrowIfDisposed();
var userRoleStore = GetUserRoleStore();
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
return await userRoleStore.GetRolesAsync(user, CancellationToken);
}
要返回角色 ID 而不是角色名称,您可以通过实现自己的 UserStore
来自定义 userRoleStore.GetRolesAsync
。
UserStore.cs
public class CustomUserStore : UserStore<IdentityUser>
{
public CustomUserStore(DbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
{
}
public override async Task<IList<string>> GetRolesAsync(IdentityUser user, CancellationToken cancellationToken = default(CancellationToken))
{
var roleNames = await base.GetRolesAsync(user, cancellationToken);
var roleIds = await Context.Set<IdentityRole>()
.Where(r => roleNames.Contains(r.Name))
.Select(r => r.Id)
.ToListAsync();
return roleIds;
}
}
注册 UserStore
services.AddDefaultIdentity<IdentityUser>()
.AddRoles<IdentityRole>()
.AddUserStore<CustomUserStore>()
.AddEntityFrameworkStores<ApplicationDbContext>()
;
services.AddScoped<DbContext, ApplicationDbContext>();
然后你将通过
获得角色id集合
var user = await _userManager.FindByNameAsync(User.Identity.Name);
var roles = await _userManager.GetRolesAsync(user);
我一直在使用一些示例在 ASP.NET Core 中使用 Identity,但有些事情让我很沮丧。即使角色模型有一个主键 Id
和一个字符串 Name
,它也是由各种内置服务传递的名称。
例如,当我调用 _userManager.GetRolesAsync(user)
时,我得到了一个字符串名称列表。如果我想要身份证怎么办?这个没有 API 所以我必须使用角色管理器来获取所有角色并映射它们。默认情况下,角色名称不受唯一键的限制,因此这是不可靠的。
我一定是漏掉了什么,但是什么?我现在的用例是我想用用户的角色填充 JWT 声明。就我而言,角色名称是我的应用程序内部的,我不想将它们公开给客户。
对于_userManager.GetRolesAsync(user)
,它调用userRoleStore.GetRolesAsync
public virtual async Task<IList<string>> GetRolesAsync(TUser user)
{
ThrowIfDisposed();
var userRoleStore = GetUserRoleStore();
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
return await userRoleStore.GetRolesAsync(user, CancellationToken);
}
要返回角色 ID 而不是角色名称,您可以通过实现自己的 UserStore
来自定义 userRoleStore.GetRolesAsync
。
UserStore.cs
public class CustomUserStore : UserStore<IdentityUser> { public CustomUserStore(DbContext context, IdentityErrorDescriber describer = null) : base(context, describer) { } public override async Task<IList<string>> GetRolesAsync(IdentityUser user, CancellationToken cancellationToken = default(CancellationToken)) { var roleNames = await base.GetRolesAsync(user, cancellationToken); var roleIds = await Context.Set<IdentityRole>() .Where(r => roleNames.Contains(r.Name)) .Select(r => r.Id) .ToListAsync(); return roleIds; } }
注册 UserStore
services.AddDefaultIdentity<IdentityUser>() .AddRoles<IdentityRole>() .AddUserStore<CustomUserStore>() .AddEntityFrameworkStores<ApplicationDbContext>() ; services.AddScoped<DbContext, ApplicationDbContext>();
然后你将通过
获得角色id集合var user = await _userManager.FindByNameAsync(User.Identity.Name); var roles = await _userManager.GetRolesAsync(user);