【问题标题】:ASP.NET Core Identity userManager.AddToRoleAsync() - add by idASP.NET Core Identity userManager.AddToRoleAsync() - 按 id 添加
【发布时间】:2021-08-23 01:29:20
【问题描述】:

我有一个自定义用户角色类,其中 CompanyId 作为外键。所以我可以创建与公司相关的用户角色。这意味着管理员角色或任何其他角色本身可以在多个公司中。我不能与公司和角色建立多对多关系,因为管理员对一家公司的要求可能因另一家公司而异。所以我在用户角色实体中添加了公司 ID。

我的问题是,用户管理器在AddToRoleAsync() 中将角色名称作为参数,我不能使用它,因为角色名称可能是多余的。如果我能够通过 ID 添加用户角色,那就太好了。是否有解决方法来实现这一点?

我目前的解决方法是将公司名称添加为角色名称的前缀。喜欢:ABC - 管理员; XYZ - 管理员。我不太喜欢这个,用户也不喜欢。

如果我可以为AddToRoleAsync()IsInRoleAync() 创建一个重载方法以通过ID 而不是名称来查找角色,那就太好了。

【问题讨论】:

  • 根据公司命名角色如何? var roleName = $"Administrator_{companyId}";

标签: c# asp.net-core asp.net-identity usermanager role-manager


【解决方案1】:

您可以扩展UserManager类并添加另一个方法以通过RoleId添加角色

public class ApplicationUserManager : UserManager<IdentityUser>
{
    private readonly UserStore<IdentityUser, IdentityRole, ApplicationDbContext, string, IdentityUserClaim<string>,
        IdentityUserRole<string>, IdentityUserLogin<string>, IdentityUserToken<string>, IdentityRoleClaim<string>> _store;

    public ApplicationUserManager(
        IUserStore<IdentityUser> store,
        IOptions<IdentityOptions> optionsAccessor,
        IPasswordHasher<IdentityUser> passwordHasher,
        IEnumerable<IUserValidator<IdentityUser>> userValidators,
        IEnumerable<IPasswordValidator<IdentityUser>> passwordValidators,
        ILookupNormalizer keyNormalizer,
        IdentityErrorDescriber errors,
        IServiceProvider services,
        ILogger<UserManager<IdentityUser>> logger)
        : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
    {
        _store = (UserStore<IdentityUser, IdentityRole, ApplicationDbContext, string, IdentityUserClaim<string>,
            IdentityUserRole<string>, IdentityUserLogin<string>, IdentityUserToken<string>, IdentityRoleClaim<string>>)store;
    }

    public virtual async Task<IdentityResult> AddToRoleByRoleIdAsync(IdentityUser user, string roleId)
    {
        ThrowIfDisposed();

        if (user == null)
            throw new ArgumentNullException(nameof(user));

        if (string.IsNullOrWhiteSpace(roleId))
            throw new ArgumentNullException(nameof(roleId));

        if (await IsInRoleByRoleIdAsync(user, roleId, CancellationToken))
            return IdentityResult.Failed(ErrorDescriber.UserAlreadyInRole(roleId));

        _store.Context.Set<IdentityUserRole<string>>().Add(new IdentityUserRole<string> { RoleId = roleId, UserId = user.Id });

        return await UpdateUserAsync(user);
    }

    public async Task<bool> IsInRoleByRoleIdAsync(IdentityUser user, string roleId, CancellationToken cancellationToken = default(CancellationToken))
    {
        cancellationToken.ThrowIfCancellationRequested();
        ThrowIfDisposed();

        if (user == null)
            throw new ArgumentNullException(nameof(user));

        if (string.IsNullOrWhiteSpace(roleId))
            throw new ArgumentNullException(nameof(roleId));

        var role = await _store.Context.Set<IdentityRole>().FindAsync(roleId);
        if (role == null)
            return false;

        var userRole = await _store.Context.Set<IdentityUserRole<string>>().FindAsync(new object[] { user.Id, roleId }, cancellationToken);
        return userRole != null;
    }
}

然后注册你自己的UserManager:

services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddUserManager<ApplicationUserManager>() // Add ApplicationUserManager
    .AddDefaultTokenProviders()
    .AddDefaultUI();

最后:

await _userManager.AddToRoleByRoleIdAsync(user, role.Id);

【讨论】:

    猜你喜欢
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2021-10-09
    • 2018-06-10
    相关资源
    最近更新 更多