2017-07-16 40 views
4

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

  • 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' 不能在通用类型或方法被用作类型参数 'TRole' 'UserStore'。 不是从'NewCo.Identity.Role'到 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole>'的隐式引用转换。

就我所见,除非这是一些(共同/对比/中)差异问题,否则所有代码都会检查出来......我错了什么?

+0

这个问题问得好!约束条件是“TRole:IdentityRole >'。由于这是* class *约束,因此不存在共同/反对。 IMO他们只是忘了添加TRoleClaim泛型参数:( –

+0

@IvanStoev谢谢,我已经提出这与ASPNETCore/Identity团队。 – series0ne

+0

https://github.com/aspnet/Identity/issues/1319 – series0ne

回答

3

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

你是一个英雄<3 – EJay