我正在将ASP.Net MVC5应用程序从Identity 1升级到2.1。一天后,我跑了。。。但我无法验证我的用户的角色(通过IsInRole或Authorize属性)。我想这是因为MVC没有解析用户和角色管理器,因为我的应用程序使用Unity DI,Identity 2似乎基于OwinContext,具有以下配置:
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
有没有一种简单的方法、教程或文档可以让Identity 2处理外部依赖项注入?
[编辑]现在Unity DI似乎有点工作了(多亏了meep)。
我修改了Startup.Auth.cs,添加到ConfigureAuth(IAppBuilder应用程序)函数:
var container = UnityConfig.Container;
var dbContext = container.Resolve<ApplicationDbContext>();
container.RegisterInstance<IAppBuilder>(app, new ContainerControlledLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
container.RegisterType<UserManager<ApplicationUser>, ApplicationUserManager>();
container.RegisterType<IRoleStore<IdentityRole, string>, RoleStore<IdentityRole>>();
container.RegisterType<RoleManager<IdentityRole>, ApplicationRoleManager>();
// [Edit 2]
app.CreatePerOwinContext<ApplicationDbContext>((options, owinContext) => container.Resolve<ApplicationDbContext>());
app.CreatePerOwinContext<UserManager<ApplicationUser>>((options, owinContext) => container.Resolve<UserManager<ApplicationUser>>());
app.CreatePerOwinContext<RoleManager<IdentityRole>>((options, owinContext) => container.Resolve<RoleManager<IdentityRole>>());
在我的UnitiConfig.cs文件中,我添加了Container singleton的声明(上面使用过)。
在IdentityConfig.cs中,我放弃了Create方法,并更改了的ctor
public ApplicationUserManager(IUserStore<ApplicationUser> store, ApplicationDbContext dbContext)
: base(store)
{
this.Initialize(dbContext);
}
private void Initialize(ApplicationDbContext dbContext)
{
// Configurer la logique de validation pour les noms d'utilisateur
this.UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// ... more code...
}
public class ApplicationRoleManager : RoleManager<IdentityRole>
{
public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore)
: base(roleStore)
{
}
}
我可以对用户进行身份验证。。。但是UserManager.GetRoles()始终为空。此外,[授权(角色="myrole"]拒绝每个用户…
好。。。谢谢大家!我明白了!
通过分析发送到SQL Server的查询(使用Express Profiler),我发现EF试图加入名为IdentityUser_Id的列上的Roles表。回到SQL Server中的表定义,我看到了两个字段:-包含ID的UserId-标识用户Id。。。始终为空!所以这就是为什么我的角色总是空的!
但为什么这两列数据相同?
我看了一下EF迁移文件。这里有一些奇怪的线路:
RenameColumn(table: "dbo.T_Securite_AspNetUserClaims", name: "User_Id", newName: "IdentityUser_Id");
AddColumn("dbo.T_Securite_AspNetUserLogins", "IdentityUser_Id", c => c.String(maxLength: 128));
AddColumn("dbo.T_Securite_AspNetUserRoles", "IdentityUser_Id", c => c.String(maxLength: 128));
所以看起来EF迁移生成器丢失了。我更改了ApplicationDbContext的OnModelCreating方法,通过告诉外键实际在哪里来帮助它:
modelBuilder.Entity<IdentityUser>()
.ToTable("T_Security_AspNetUsers"); // Yes... I changed the table name : maybe the source of the problem !
modelBuilder.Entity<IdentityUser>()
.HasMany(u => u.Roles)
.WithOptional()
.HasForeignKey(r => r.UserId);
modelBuilder.Entity<IdentityUser>()
.HasMany(u => u.Logins)
.WithOptional()
.HasForeignKey(l => l.UserId);
modelBuilder.Entity<IdentityUser>()
.HasMany(u => u.Claims)
.WithOptional()
.HasForeignKey(c => c.UserId);
现在EF迁移文件看起来更好了。我有我的用户的角色,[授权(角色="xxx")]似乎可以工作!