0

So i'm having issues with Identity and UserRoles. I have inherited from the base classes, and then added some custom fields. The user object now has a person, which two other classes inherit from (Applicant and Reviewer).

I have tried so much to get this working in terms of re-ordering the mappings of the tables in the model builder, removing my custom inherited classes, forcing lazy loading.

Any suggestions or help on this would be greatly appreciated.

This is the applicant context.

 public class ApplicantContext : IdentityDbContext<User>
        {
            public ApplicantContext()
                : base("ApplicantDbConnection")
            {
                this.Configuration.LazyLoadingEnabled = true;
            }


            public DbSet<Person> People { get; set; }
            public DbSet<Applicant> Graduates { get; set; }
            public DbSet<Reviewer> Reviewers { get; set; }



            //stop pluralising generated tables
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);

                modelBuilder.Entity<User>().ToTable("Users");
                modelBuilder.Entity<Role>().HasKey<string>(r => r.Id).ToTable("Roles");
                modelBuilder.Entity<User>().HasRequired(i => i.Person).WithMany().HasForeignKey<int>(i => i.PersonID);
                modelBuilder.Entity<User>().HasMany<UserRole>((User u) => u.UserRoles);
                modelBuilder.Entity<UserRole>().HasKey(r => new { UserId = r.UserId, RoleId = r.RoleId }).ToTable("UserRoles");

                modelBuilder.Entity<IdentityUser>()
                   .ToTable("Users");

                modelBuilder.Entity<IdentityRole>()
                    .ToTable("Roles");

                modelBuilder.Entity<IdentityUserRole>()
                    .ToTable("UserRoles");

                modelBuilder.Entity<IdentityUserClaim>()
                    .ToTable("UserClaims");

                modelBuilder.Entity<IdentityUserLogin>()
                    .ToTable("UserLogins");



            }
        }

Db Initialiser. The database side of things seems all fine, but when i log into the system, the login is successful, however when it redirects to Home controller Index, the Index page uses [Authorize(Roles="Reviewer")] and this is where it fails. It says the user is not in that role, however in the database the UserId is paired with the RoleID in the UserRoles table. Therefore the User's role is null.

public class DataInitialiser : CreateDatabaseIfNotExists<ApplicantContext>
    {

        protected override void Seed(ApplicantContext context)
        {

            var manager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
            manager.Create(new IdentityRole("Reviewer"));
            manager.Create(new IdentityRole("Applicant"));

            ApplicationUserManager userManager = new ApplicationUserManager(new UserStore<User>(context));
            User user = new User
            {
                Person = new Reviewer
                {

                    FirstName = "Grant",
                    MiddleNames = "Mark",
                    Surname = "Weatherston",
                    OfficeID = 1,
                },
                Email = "test@test.com",
                UserName = "test@test.com",
                PhoneNumber = "0123456789",
            };

            userManager.Create(user, "Password123");
            userManager.AddToRole(user.Id, "Reviewer");

            context.SaveChanges();

            base.Seed(context);
        }

    }

Custom Role class inheriting from IdentityRole.

 public class Role : IdentityRole
    {
        public Role() { }
        public Role(string name) :base(name)
        {
        }

    }

Custom User class inherits from identity user with adding property Person.

 public class User : IdentityUser
    {
        public User() { }

        public int PersonID { get; set; }

        [ForeignKey("PersonID")]
        public virtual Person Person { get; set; }

        public virtual ICollection<UserRole> UserRoles {get;set;}

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }

Custom User Role Class.

    public class UserRole : IdentityUserRole
        {

        }

Custom Role Manager.

public class ApplicationRoleManager : RoleManager<IdentityRole>
    {

        public ApplicationRoleManager(RoleStore<IdentityRole> roleStore)
            : base(roleStore)
        {

        }

    }

Custom UserManager

public class ApplicationUserManager : UserManager<User>
    {
        public ApplicationUserManager(IUserStore<User> store)
            : base(store)
        {
        }

   }
Gweaths
  • 85
  • 11

1 Answers1

0

This is a bit over due, but I solved this problem by adding the following line right before the userIdentity declaration:

await manager.UpdateSecurityStampAsync(this.Id);

Where manager is an instance of UserManager

This resets the Security Stamp with the Current User's Id.

Ali Prasla
  • 11
  • 2