2017-07-16 71 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