使用Unity的MVC5应用程序内的ASP.Net Identity 2.1

时间:2014-09-11 10:48:19

标签: asp.net-mvc unity-container asp.net-identity

我将ASP.Net MVC5应用程序从Identity 1升级到2.1。 一天后我开始运行...但我无法验证用户的角色(通​​过IsInRole或授权属性)。 我想这是因为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 app)功能:

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单例的声明(在上面使用过)。

在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()始终为空。 此外[授权(Roles =&#34; myrole&#34;]拒绝每个用户......

1 个答案:

答案 0 :(得分:4)

好的...谢谢大家! 我懂了!

通过分析查询发送到SQL Server(使用Express Profiler),我看到EF尝试在名为IdentityUser_Id的列上加入角色表。 回到SQL Server中的表定义我看到了2个字段: - 包含id的UserId - IdentityUser_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 Migration文件看起来更好了。 我的用户有角色,[授权(角色=“xxx”)]似乎有效!