Reputation: 1153
I'm upgrading my ASP.Net MVC5 application from Identity 1 to 2.1. After one day I made it run... but I can't verify roles for my users (by IsInRole or Authorize Attribute). I guess it is because MVC doesn't resolve the user and role manager since my application uses Unity DI and Identity 2 seems to be based on OwinContext with the following configuration :
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
Is there a simple way, tutorial or documentation to have Identity 2 working with external dependency injection ?
[Edit] Now Unity DI seems to work a little (thanks to meep).
I modified Startup.Auth.cs, adding to ConfigureAuth(IAppBuilder app) function :
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>>());
In my UnitiConfig.cs file I added the declaration for a Container singleton (used above).
In IdentityConfig.cs, I dropped the Create method and changed the ctor for
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)
{
}
}
I can authenticate the users... but UserManager.GetRoles() is always empty. Moreover [Authorize(Roles="myrole"] rejects every user...
Upvotes: 3
Views: 3856
Reputation: 1153
OK... Thank you all ! I got it !
By profiling the query send to SQL Server (using Express Profiler) I saw that EF tryed to join Roles Table On a column named IdentityUser_Id. Back to the table definition in SQL Server I saw 2 fields : - UserId containing the ids - IdentityUser_Id... always null ! So that's why my Roles were always empty !
But why theses 2 columns for the same data ?
I took a look at the EF migration file. Here were some strange lines :
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));
So it looks like the EF Migration generator was lost. I changed the OnModelCreating method for ApplicationDbContext to help it a little by telling where the foreign keys are actually :
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);
Now the EF Migration file is looking better. I have roles for my users and the [Authorize(Role="xxx")] seems to work !
Upvotes: 4