c# - ASP.NET Core Identity,如何覆盖 IdentityRole 名称唯一索引?我想存储关于租户的重复名称

标签 c# asp.net-core asp.net-identity

我正在编写 IdentityRoleManager 的扩展以允许 Multi-Tenancy 角色。不同租户中的角色可以同名,他们可以将自己的声明分配给角色。

如何在表中允许重复的角色名称?我打算通过 RoleManager 实现的每个租户的角色名称都是唯一的。

尝试过 OnModelCreating FluentApi,但它没有像 EF6 那样提供要作为注释传递的对象

builder.Entity().ToTable("PenRoles") .Property(p => p.Name).HasAnnotation("Index", new _____{ });

怎么做?

最佳答案

更改角色流畅的 api 配置:

public class RoleConfiguration : IEntityTypeConfiguration<Role>
{
    public void Configure(EntityTypeBuilder<Role> builder)
    {
        builder.Metadata.RemoveIndex(new[] { builder.Property(r => r.NormalizedName).Metadata });

        builder.HasIndex(r => new { r.NormalizedName, r.ApplicationId }).HasName("RoleNameIndex").IsUnique();
    }
}

然后覆盖 RoleValidator:

public class MyRoleValidator : RoleValidator<Role>
{
    public override async Task<IdentityResult> ValidateAsync(RoleManager<Role> manager, Role role)
    {
        var roleName = await manager.GetRoleNameAsync(role);
        if (string.IsNullOrWhiteSpace(roleName))
        {
            return IdentityResult.Failed(new IdentityError
            {
                Code = "RoleNameIsNotValid",
                Description = "Role Name is not valid!"
            });
        }
        else
        {
            var owner = await manager.Roles.FirstOrDefaultAsync(x => x.ApplicationId == role.ApplicationId && x.NormalizedName == roleName);

            if (owner != null && !string.Equals(manager.GetRoleIdAsync(owner), manager.GetRoleIdAsync(role)))
            {
                return IdentityResult.Failed(new IdentityError
                {
                    Code = "DuplicateRoleName",
                    Description = "this role already exist in this App!"
                });
            }
        }
        return IdentityResult.Success;
    }
}

然后注册到 DI 容器并更改启动文件中的 asp net identity 配置以使用此类:

    public static IServiceCollection ConfigureIdentity(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddScoped<IRoleValidator<Role>, MyRoleValidator>(); //this line...
        services.AddIdentity<ApplicationUser, Role>(options =>
        {
            options.Password.RequiredLength = configuration.GetSection(nameof(IdentitySettings)).Get<IdentitySettings>().PasswordRequiredLength;
            options.Password.RequireLowercase = configuration.GetSection(nameof(IdentitySettings)).Get<IdentitySettings>().PasswordRequireLowercase;
            options.Password.RequireUppercase = configuration.GetSection(nameof(IdentitySettings)).Get<IdentitySettings>().PasswordRequireUppercase;
            options.Password.RequireNonAlphanumeric = configuration.GetSection(nameof(IdentitySettings)).Get<IdentitySettings>().PasswordRequireNonAlphanumeric;
            options.Password.RequireDigit = configuration.GetSection(nameof(IdentitySettings)).Get<IdentitySettings>().PasswordRequireDigit;
        })
            .AddRoleValidator<MyRoleValidator>() //this line ...
            .AddEntityFrameworkStores<SepidIdentityContext>()
            .AddDefaultTokenProviders();

        return services;
    }

关于c# - ASP.NET Core Identity,如何覆盖 IdentityRole 名称唯一索引?我想存储关于租户的重复名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57359988/

相关文章:

c# - 在 Controller 中生成 token

c# - 对 Winform 的叠加控制

c# - 制作空心体素锥

asp.net - 使用 SQL 数据库部署 ASP.NET Core Web API

.net - 使用 C# 反序列化 Json 对象

c# - JwtSecurityToken 过期时间无效 .NET Core 3.1

c# - ASP.NET Core Identity ApplicationUser 与域模型实体关系的分离

asp.net - 如何为 asp.net 身份创建安全标记值 (IUserSecurityStampStore)

c# - 无法从 'System.Collections.Generic.IEnumerable<int>' 转换为 'System.Linq.IQueryable<int?>

c# - 将特殊字符转换为 Html 编码字符