PaulBinder
PaulBinder

Reputation: 2052

UserManager.IsInRole returns false

I have a seeded user that is created and then added to the role "SuperAdmin". Yet when trying to perform "IsInRole" from the user manager , I always get "false".

I have turned on lazy loading as suggested in previous answers I found, with no luck.

In my database I see the entry in the IdentityUserRole table. It contains the correct user id and roleid. The userId matches my accounts id on my ApplicationUser table

Note: I did move my context and applicatuonuser out of the web project and into my DAL project

My new context derives from IdentityDbContext and passes in as the generic user. I believe this has something to do with it as when I look at the table 'IdentityUserRole' I see the following columns

UserID | RoleID | ApplicationUser_ID | Role_ID

when I run a profiler I see that entityframework attempts to join the role with the ApplicationUser_ID. Yet this is null. The UserID is what is populated

My Controller (where it returns false

   var t = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            //next line Fails due to FK, because user is already in role...
            //t.AddToRole(User.Identity.GetUserId(), "SuperAdmin");

            var users = UserManager.Users;

            bool ffalse = t.IsInRole(User.Identity.GetUserId(), "SuperAdmin");
            var false2 = User.IsInRole("SuperAdmin");
            var false3 = UserManager.IsInRole(User.Identity.GetUserId(), "SuperAdmin");

My DataContext

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using OrangeBasement.Models;

namespace OrangeBasement.DAL
{
    public class ObContext : IdentityDbContext<ApplicationUser>
    {
        public ObContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
            Configuration.LazyLoadingEnabled = true;
            Database.SetInitializer(new ObContextInitializer());
        }

        public static ObContext Create()
        {
            return new ObContext();
        }

        public DbSet<Account> Accounts { get; set; }
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<BlogEntry> BlogEntries { get; set; }
        public DbSet<Portfolio> Portfolios { get; set; }
        public DbSet<PortfolioEntry> PortfolioEntries { get; set; }
        public DbSet<PortfolioEntryType> PortfolioEntryTypes { get; set; }
        public DbSet<ObImage> ObImages { get; set; }
        public DbSet<Testimonial> Testimonials { get; set; }
        public DbSet<TestimonialEntry> TestimonialEntries { get; set; }
        public DbSet<Special> Specials { get; set; }
        public DbSet<IndexMessage> IndexMessages { get; set; }
        public DbSet<ObUser> ObUsers { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            this.Configuration.LazyLoadingEnabled = true;
            modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
            modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
            modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        }

        public class ObContextInitializer : DropCreateDatabaseIfModelChanges<ObContext>
        {
            protected override void Seed(ObContext context)
            {
                if (!context.Roles.Any(r => r.Name == "SuperAdmin"))
                {
                    var store = new RoleStore<IdentityRole>(context);
                    var manager = new RoleManager<IdentityRole>(store);
                    var role = new IdentityRole {Name = "SuperAdmin"};

                    manager.Create(role);
                }

                if (!context.Users.Any(u => u.Email == "[email protected]"))
                {
                    var store = new UserStore<ApplicationUser>(context);
                    var manager = new UserManager<ApplicationUser>(store);
                    var passwordHash = new PasswordHasher();
                    var password = passwordHash.HashPassword("password");
                    var user = new ApplicationUser
                    {
                        UserName = "[email protected]",
                        PasswordHash = password,
                        Email = "[email protected]",

                    };

                    manager.Create(user);
                    manager.AddToRole(user.Id, "SuperAdmin");
                }

                if (!context.Users.Any(u => u.Email == "[email protected]"))
                {
                    var store = new UserStore<ApplicationUser>(context);
                    var manager = new UserManager<ApplicationUser>(store);
                    var passwordHash = new PasswordHasher();
                    var password = passwordHash.HashPassword("Nov04198!");
                    var user = new ApplicationUser
                    {
                        UserName = "[email protected]",
                        PasswordHash = password,
                        Email = "[email protected]",

                    };

                    manager.Create(user);
                    manager.AddToRole(user.Id, "SuperAdmin");
                }

                context.Accounts.Add(new Account { AccountName = "Seed1" });
                context.Blogs.Add(new Blog { AccountId = 1, Title = "Seed1 Title", SubTitle = "Seed1 SubTitle" });
                context.BlogEntries.Add(new BlogEntry { BlogId = 1, Title = "Seed1 Blog Entry", SubTitle = "Seed1 Blog Sub Title", Body = "Seed data.", Date = DateTime.Now });
                context.Portfolios.Add(new Portfolio { AccountId = 1, Title = "Seed1 Portfolio", SubTitle = "Seed1 Sub Title" });
                context.PortfolioEntryTypes.Add(new PortfolioEntryType { Description = "Seed1 Type", PortfolioId = 1 });
                context.Testimonials.Add(new Testimonial { AccountId = 1, Title = "Testimonials", SubTitle = "Sub Title" });
                context.TestimonialEntries.Add(new TestimonialEntry { TestimonialId = 1, Author = "Paul", Body = "Test Body", Date = DateTime.Now });
                context.Specials.Add(new Special { AccountId = 1, Title = "Title", Body = "Body", Footer = "Footer" });
                context.IndexMessages.Add(new IndexMessage { AccountId = 1, LinkPath = "/Special/", Message = "Check out our specials" });
                base.Seed(context);
            }
        }
    }
}

My Web Config

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301880
  -->
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="DefaultConnection" connectionString="Server=tcp:evr7sifn7h.database.windows.net,1433;Database=Test_OrangeBasementCSM;User ID=user@evr7sifn7h;Password=pass;Trusted_Connection=False;Encrypt=True;Connection Timeout=30; MultipleActiveResultSets=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <authentication mode="None" />
    <customErrors mode="On" />
    <roleManager enabled="true" />
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" maxRequestLength="1048576" />
  </system.web>
  <system.webServer>
    <modules>
      <remove name="FormsAuthentication" />
    </modules>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

Upvotes: 3

Views: 1107

Answers (1)

PaulBinder
PaulBinder

Reputation: 2052

So , as I stated above, after using a profiler I found that Roles were not correctly joining with Users. This led me down the path to find a way to setup ForeignKeys on Model creation.

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {

            Configuration.LazyLoadingEnabled = true;

            var user = modelBuilder.Entity<ApplicationUser>()
    .ToTable("AspNetUsers");
            user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
            user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
            user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
            user.Property(u => u.UserName).IsRequired();

            modelBuilder.Entity<IdentityUserRole>()
                .HasKey(r => new { r.UserId, r.RoleId })
                .ToTable("AspNetUserRoles");

            modelBuilder.Entity<IdentityUserLogin>()
                .HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey })
                .ToTable("AspNetUserLogins");

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

            var role = modelBuilder.Entity<IdentityRole>()
                .ToTable("AspNetRoles");
            role.Property(r => r.Name).IsRequired();
            role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);


            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        } 

Now, when pulling users down, their roles come attached. IsInRole works correctly and so does Authorize.

Upvotes: 4

Related Questions