3

I've created a new application with ASP.NET MVC5, using Individual User Accounts for security and Code-First Migrations for the Models/Database modeling. All options are default.

I want to setup custom Users and Roles to it, so i created a Seed using RoleManager and UserManager just to populate the Database. It works fine, create 3 Users, 3 Roles and set each User's Role correctly.

I can log in to the application correctly. The problem is that i can't execute any Identity method using the User, which is the logged User, the only things that i can get is the User.Identity.IsAuthenticated value, and the User.Identity.Name, which are correct. Every other method like Roles.GetRolesForUser("John"), or User.IsInRole("Student"), always generates this exception:

ProviderException : The Role Manager feature has not been enabled.

So okay, as in this article, i managed to insert the the <roleManager enabled="true" /> in the Web.config, and now it takes a really long time to respond, and generates Exceptions like:

Referring to:

Roles.IsUserInRole("Student")

Generates:

HttpException

Referring to:

Roles.GetRolesForUser(User.Identity.Name)

Generates:

NullReferenceException

Accessing the About page with a User in Student role logged in:

[Authorize(Roles="Teacher")]
public ActionResult About()
{
    ViewBag.Message = "Your application description page.";

    return View();
}

Generates:

SqlException
HttpException

It's like i have no connection to the Database at all, which is LocalDB, automatically generated and i could populate in the Seed Method and even make Login to the application.

I could even load data from the AspNetUsers table and show it in the View using the code below:

using (Models.ApplicationDbContext db = new Models.ApplicationDbContext())
{
    List<Models.ApplicationUser> Users = db.Users.ToList();

    ViewBag.Users = Users;
}

return View();

PLEASE HELP :'(


Here's the Seed code, that works fine, so it can connect to the Database using the Identity engine.

protected override void Seed(LocalBDAuthTest.Models.ApplicationDbContext context)
{
    #region Create Roles Student, Teacher e Administrator

    var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

    // Student
    if (!RoleManager.RoleExists("Student"))
    {
        RoleManager.Create(new IdentityRole("Student"));
    }

    // Teacher
    if (!RoleManager.RoleExists("Teacher"))
    {
        RoleManager.Create(new IdentityRole("Teacher"));
    }

    // Administrator
    if (!RoleManager.RoleExists("Administrator"))
    {
        RoleManager.Create(new IdentityRole("Administrator"));
    }

    #endregion

    #region Create Users for Student, Teacher e Administrator Roles.

    var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));


    // Create a Student user and set it's role to Student
    if (!context.Users.Any(u => u.UserName == "John"))
    {
        var Student = new ApplicationUser() { UserName = "John" };
        var Result = UserManager.Create(Student, "123456");
    }
    if (!UserManager.FindByName("John").Roles.Any())
    {
        UserManager.AddToRole(UserManager.FindByName("John").Id, "Student");
    }


    // Create a Teacher user and set it's role to Teacher
    if (!context.Users.Any(u => u.UserName == "Arnold"))
    {
        var Teacher = new ApplicationUser() { UserName = "Arnold" };
        var Result = UserManager.Create(Teacher, "123456");
        UserManager.AddToRole(Teacher.Id, "Teacher");
    }
    if (!UserManager.FindByName("Arnold").Roles.Any())
    {
        UserManager.AddToRole(UserManager.FindByName("Arnold").Id, "Teacher");
    }


    // Create a Administrator user and set it's role to Administrator
    if (!context.Users.Any(u => u.UserName == "Caroline"))
    {
        var Administrator = new ApplicationUser() { UserName = "Caroline" };
        var Result = UserManager.Create(Administrator, "123456");
        UserManager.AddToRole(Administrator.Id, "Administrator");
    }
    if (!UserManager.FindByName("Caroline").Roles.Any())
    {
        UserManager.AddToRole(UserManager.FindByName("Caroline").Id, "Administrator");
    }

    #endregion
    }
Community
  • 1
  • 1
Edgar Froes
  • 768
  • 8
  • 20

1 Answers1

5

This is due to having a mix of both ASP.NET Identity and ASP.NET Membership, having done this:

<system.web>
    <roleManager enabled="true" />
</system.web>

You enabled membership SqlRoleProvider, which use the role store in the default SQL Express instance in a database in your Web site's \app_dir folder.

If you open your machine.config, you'll find:

<connectionStrings>
  <add name="LocalSqlServer" 
    connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;
      AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
      providerName="System.Data.SqlClient"/>
</connectionStrings>
.
.
.
<roleManager>
  <providers>
    <add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" ...
</providers>
</roleManager>

Most likely you don't have SQL Express installed, and that's why you are getting timeouts and SQL exceptions.

For ASP.NET Identity DON'T use System.Web.Security.Roles (it is part of the ASP.NET Membership) but use Microsoft.AspNet.Identity.RoleManager instead.

MK.
  • 5,139
  • 1
  • 22
  • 36
  • Damn, you are right! I wiped roleManager form Web.config. Now it leaves only to the Database Connection error. If i put [Authorize(Roles = "rolename")] in some Action, then go the View of that Action, i get long timeouts, and after the long wait, SqlExceptions and HttpExceptions, saying that they can't connect to the Database. How is that possible? I use LocalDB in it's latest version, it's installed, along with SQL Express and Visual Studio 2013 Ultimate, which should come with the whole package, right? – Edgar Froes Jan 17 '14 at 16:10
  • Not sure about your exact setup, recheck your web.config connection strings also recheck your code for connection keys being used. its gotta be something you have modified! – MK. Jan 17 '14 at 16:34
  • Also note that Authorize attribute is not supposed to hit the database, it operates on `IPrincipal` User in the current `HttpContext` and iterates over the role claims stored in it. – MK. Jan 17 '14 at 17:21
  • Ops, i still had in there somehow... Nailed it! I fixed it and now i can put my hair back in my head again haha, THANKS BRO! <3 – Edgar Froes Jan 17 '14 at 17:33
  • It's a shame i can't just vote up your answer because of my reputation. – Edgar Froes Jan 17 '14 at 17:35