AspNetCore.标识不能与自定义用户/角色实现一起工作

本文关键字:角色 实现 一起 工作 用户 标识 不能 自定义 AspNetCore | 更新日期: 2023-09-27 17:54:21

因为我倾向于将Guid作为我的主键类型,所以我的UserRole类实现如下

public class User : IdentityUser<Guid, UserClaim, UserRole, UserLogin>
{
}
public class Role : IdentityRole<Guid, UserRole, RoleClaim>
{
}

注意UserClaim, UserRole, UserLogin &RoleClaim都以相同的方式实现

这是我的DbContext实现

public class ApplicationDbContext : IdentityDbContext<User, Role, Guid, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
{
}

到目前为止都很好,除了AspNetCore的新DI容器似乎不喜欢我默认的自定义实现。下面这行代码,来自我的Startup.cs文件,抛出如下所示的错误

services
    .AddIdentity<User, Role>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

GenericArguments[0],"NewCo.DomainModel.Models.Identity。用户',"Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore"4[摘要、TRole TContext, TKey)"违反了类型'TUser'的约束。

我假设这是因为默认的Identity gremlin被实现为使用IdentityUser<string>,而我使用的是IdentityUser<Guid>

接下来我该做什么?(I'm all out ideas)

注意:我是基于微软官方的。net Core和ASP构建的。. NET Core版本截至周一(2016年6月27日)和Visual Studio Update 3(如果这对任何人有任何帮助)

AspNetCore.标识不能与自定义用户/角色实现一起工作

由于使用的是自定义键类型,因此必须在调用AddEntityFrameworkStores:

时指定它。
services
    .AddIdentity<User, Role>()
    .AddEntityFrameworkStores<ApplicationDbContext, Guid>()
    .AddDefaultTokenProviders();

我最终得到了这样的解决方案:
实际上我做了自己的抽象IdentityDbContext然后你可以通过任何自定义模型,唯一的问题是当创建db EF添加一个discriminator字段到除用户和角色(继承)以外的所有表

public abstract class ApplicationDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> : IdentityDbContext<TUser, TRole, TKey>
    where TUser : IdentityUser<TKey>
    where TRole : IdentityRole<TKey>
    where TKey : IEquatable<TKey>
    where TUserClaim : IdentityUserClaim<TKey>
    where TUserRole : IdentityUserRole<TKey>
    where TUserLogin : IdentityUserLogin<TKey>
    where TRoleClaim : IdentityRoleClaim<TKey>
    where TUserToken : IdentityUserToken<TKey>
{
    public ApplicationDbContext(DbContextOptions options) : base(options) { }
    protected ApplicationDbContext() { }
    public new DbSet<TRoleClaim> RoleClaims { get; set; }
    public new DbSet<TRole> Roles { get; set; }
    public new DbSet<TUserClaim> UserClaims { get; set; }
    public new DbSet<TUserLogin> UserLogins { get; set; }
    public new DbSet<TUserRole> UserRoles { get; set; }
    public new DbSet<TUser> Users { get; set; }
    public new DbSet<TUserToken> UserTokens { get; set; }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}
public class AppDbContext : ApplicationDbContext<ApplicationUser, ApplicationRole, Guid, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationRoleClaim, ApplicationUserToken>
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {
    }
    //public new DbSet<ApplicationUserClaim> UserClaims { get; set; }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}
  services.AddIdentity<ApplicationUser, ApplicationRole>()
                .AddEntityFrameworkStores<AppDbContext, Guid>()
                .AddDefaultTokenProviders()
                .AddUserStore<UserStore<ApplicationUser, ApplicationRole, AppDbContext, Guid>>()
                .AddRoleStore<RoleStore<ApplicationRole, AppDbContext, Guid>>()
public class ApplicationUser : IdentityUser<Guid>
{
    public ApplicationUser()
    {
        //this.Id = Guid.NewGuid();
    }
    public ApplicationUser(string userName) : this() { this.UserName = userName; }
    public Guid ClientId { get; set; }
    //public new ICollection<ApplicationUserClaim> Claims { get; set; }
}
//public class ApplicationRole : IdentityRole<Guid, ApplicationUserRole, ApplicationRoleClaim>
public class ApplicationRole : IdentityRole<Guid>
{
    public ApplicationRole()
    {
        //this.Id = Guid.NewGuid();
    }
    public ApplicationRole(string name) : this() { this.Name = name; }
}
public class ApplicationRoleClaim : IdentityRoleClaim<Guid> { }
//[NotMapped]
public class ApplicationUserClaim : IdentityUserClaim<Guid> { }
public class ApplicationUserLogin : IdentityUserLogin<Guid> { }
public class ApplicationUserRole : IdentityUserRole<Guid> { }
public class ApplicationUserToken : IdentityUserToken<Guid> { }

"UserStore ' 4[TUser,TRole,TContext,TKey]'违反的约束"摘要"类型。"

您需要使用Guid创建UserStore,以及更改DbContext

public class ApplicationUser : IdentityUser<Guid> { }
public class ApplicationRole : IdentityRole<Guid> { }
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, Guid>
{
    public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
    {
    }
}

New ApplicationDbContext inherit

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}

In your startup.cs

services
    .AddIdentity<ApplicationUser, ApplicationRole>()
    .AddUserStore<ApplicationUserStore>()
    .AddEntityFrameworkStores<ApplicationDbContext, Guid>()
    .AddDefaultTokenProviders();

在使用自定义用户和角色实体的情况下指定Key到. addentityframeworkstore()方法。在启动

注册身份时
.AddEntityFrameworkStores<IdentityDbContext, TKey>()

,因为它使用默认的键类型字符串,在其他键类型的情况下会导致错误。