ASP.NET Core - custom AspNetCore.Identity implementation not working

匿名 (未验证) 提交于 2019-12-03 02:20:02

问题:

I'm building a completely custom AspNetCore.Identity Implementation because I want TKey to be System.Guid across the board. With respect, I have derived types for...

  • 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 is the problem child!

Implementation

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

Error

The type 'NewCo.Identity.Role' cannot be used as type parameter 'TRole' in the generic type or method 'UserStore'. There is no implicit reference conversion from 'NewCo.Identity.Role' to 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole>'.

As far as I can see, unless this is some (co/contra/in)variance issue, all the code checks out...what did I get wrong?

回答1:

Your ApplicationUserStore needs the RoleClaim at the end too (don't forget to update the related NuGet packages, otherwise you can't use these new additions):

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

Plus your ApplicationRoleStore should provide how to create the RoleClaim,

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

And also the ApplicationUserStore should provide these mappings too:

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

Then redirect built-in services to your custom services:

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

now introduce your custom services:

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!