我一直在使用一些示例来研究ASP.NET Core中的Identity,这让我感到沮丧。即使角色模型有一个主键Id
和一个字符串Name
,它也是通过各种内置服务传递的名称。
例如,当我呼叫_userManager.GetRolesAsync(user)
时,我会返回一个字符串名称列表。如果我需要身份证怎么办?没有API,因此我必须使用角色管理器来获取所有角色并映射它们。默认情况下,角色名称不受唯一键的约束,因此不可靠。
我一定很想念什么,但是呢?现在,我的用例是我想用用户角色填充JWT声明。就我而言,角色名称是应用程序内部的角色,我不想将其公开给客户端。
答案 0 :(得分:1)
对于_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而不是角色名称,可以通过实现自己的userRoleStore.GetRolesAsync
来定制UserStore
。
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);