【问题标题】:ASP.NET Core - custom AspNetCore.Identity implementation not workingASP.NET Core - 自定义 AspNetCore.Identity 实现不起作用
【发布时间】:2017-07-16 10:47:48
【问题描述】:

我正在构建一个完全自定义的 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>
    {
    }
}

错误

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

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

【问题讨论】:

  • 好问题!约束是where TRole : IdentityRole&lt;TKey, TUserRole, IdentityRoleClaim&lt;TKey&gt;&gt;。由于这是 class 约束,因此没有协变/逆变。 IMO 他们只是忘记添加TRoleClaim 通用参数:(
  • @IvanStoev 谢谢,我已经向 ASPNETCore/Identity 团队提出了这个问题。

标签: c# entity-framework asp.net-identity


【解决方案1】:

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

    ApplicationUserStore : UserStore<
            User, Role, ApplicationDbContext, 
            Guid, UserClaim, UserRole, 
            UserLogin, UserToken, RoleClaim>

加上您的ApplicationRoleStore 应该提供如何创建RoleClaim

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

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
    };
}

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

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>();

现在介绍您的自定义服务:

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();

【讨论】:

  • 你是英雄
猜你喜欢
  • 2023-03-16
  • 2021-12-11
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-20
  • 1970-01-01
相关资源
最近更新 更多