ASP.NET Core - 自定义 AspNetCore.Identity 实现不起作用

ser*_*0ne 4 c# entity-framework asp.net-identity

我正在构建一个完全自定义的 AspNetCore.Identity 实现,因为我想要TKey全面System.Guid。恕我直言,我已经派生了类型......

  • Role : IdentityRole<Guid, UserRole, RoleClaim>
  • RoleClaim : IdentityRoleClaim<Guid>
  • User : IdentityUser<Guid, UserClaim, UserRole, UserLogin>
  • UserClaim : IdentityUserClaim<Guid>
  • UserLogin : IdentityUserLogin<Guid>
  • UserRole : IdentityUserRole<Guid>
  • UserToken : IdentityUserToken<Guid>

  • ApplicationDbContext : IdentityDbContext<User, Role, Guid, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>

  • ApplicationRoleManager : RoleManager<Role>
  • ApplicationRoleStore : RoleStore<Role, ApplicationDbContext, Guid, UserRole, RoleClaim>
  • ApplicationSignInManager : SignInManager<User>
  • ApplicationUserManager : UserManager<User>
  • **ApplicationUserStore** : UserStore<User, Role, ApplicationDbContext, Guid, UserClaim, UserRole, UserLogin, UserToken>

ApplicationUserStore是问题孩子!

执行

namespace NewCo.Identity
{
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    using System;

    public sealed class Role : IdentityRole<Guid, UserRole, RoleClaim>
    {
    }
}

namespace NewCo.Identity
{
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    using System;

    public sealed class UserRole : IdentityUserRole<Guid>
    {
    }
}

namespace NewCo.Identity
{
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    using System;

    public sealed class RoleClaim : IdentityRoleClaim<Guid>
    {
    }
}

// The problem is here...

namespace NewCo.Identity
{
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    using System;
    using System.Security.Claims;

    public sealed class ApplicationUserStore : UserStore<User, Role, ApplicationDbContext, Guid, UserClaim, UserRole, UserLogin, UserToken>
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

错误

类型“NewCo.Identity.Role”不能用作泛型类型或方法“UserStore”中的类型参数“TRole”。没有从“NewCo.Identity.Role”到“Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole>”的隐式引用转换。

据我所知,除非这是一些(co/contra/in)方差问题,否则所有代码都会检查......我做错了什么?

Vah*_*idN 5

最后你也ApplicationUserStore需要RoleClaim(不要忘记更新相关的 NuGet 包,否则你无法使用这些新添加的内容):

    ApplicationUserStore : UserStore<
            User, Role, ApplicationDbContext, 
            Guid, UserClaim, UserRole, 
            UserLogin, UserToken, RoleClaim>
Run Code Online (Sandbox Code Playgroud)

另外你ApplicationRoleStore应该提供如何创建RoleClaim

protected override RoleClaim CreateRoleClaim(Role role, Claim claim)
{
    return new RoleClaim
    {
        RoleId = role.Id,
        ClaimType = claim.Type,
        ClaimValue = claim.Value
    };
}
Run Code Online (Sandbox Code Playgroud)

并且还ApplicationUserStore应该提供这些映射:

protected override UserClaim CreateUserClaim(User user, Claim claim)
{
    var userClaim = new UserClaim { UserId = user.Id };
    userClaim.InitializeFromClaim(claim);
    return userClaim;
}

protected override UserLogin CreateUserLogin(User user, UserLoginInfo login)
{
    return new UserLogin
    {
        UserId = user.Id,
        ProviderKey = login.ProviderKey,
        LoginProvider = login.LoginProvider,
        ProviderDisplayName = login.ProviderDisplayName
    };
}

protected override UserRole CreateUserRole(User user, Role role)
{
    return new UserRole
    {
        UserId = user.Id,
        RoleId = role.Id
    };
}

protected override UserToken CreateUserToken(User user, string loginProvider, string name, string value)
{
    return new UserToken
    {
        UserId = user.Id,
        LoginProvider = loginProvider,
        Name = name,
        Value = value
    };
}
Run Code Online (Sandbox Code Playgroud)

然后将内置服务重定向到您的自定义服务:

services.AddScoped<UserStore<User, Role, ApplicationDbContext, int, UserClaim, UserRole, UserLogin, UserToken, RoleClaim>, ApplicationUserStore>();
services.AddScoped<UserManager<User>, ApplicationUserManager>();
services.AddScoped<RoleManager<Role>, ApplicationRoleManager>();
services.AddScoped<SignInManager<User>, ApplicationSignInManager>();
services.AddScoped<RoleStore<Role, ApplicationDbContext, int, UserRole, RoleClaim>, ApplicationRoleStore>();
services.AddScoped<IEmailSender, AuthMessageSender>();
services.AddScoped<ISmsSender, AuthMessageSender>();
Run Code Online (Sandbox Code Playgroud)

现在介绍您的定制服务:

services.AddIdentity<User, Role>(identityOptions =>
            {
             // ...
            }).AddUserStore<ApplicationUserStore>()
              .AddUserManager<ApplicationUserManager>()
              .AddRoleStore<ApplicationRoleStore>()
              .AddRoleManager<ApplicationRoleManager>()
              .AddSignInManager<ApplicationSignInManager>()
              // You **cannot** use .AddEntityFrameworkStores() when you customize everything
              //.AddEntityFrameworkStores<ApplicationDbContext, int>()
              .AddDefaultTokenProviders();
Run Code Online (Sandbox Code Playgroud)