1

I have a site that I want to differentiate between ASP.NET Identity users and External Users using roles.

I have created my roles using:

    ApplicationDbContext.Roles.Add(new IdentityRole()
    {
        Name = "External"
    });
    ApplicationDbContext.Roles.Add(new IdentityRole()
    {
        Name = "Internal"
    });
    ApplicationDbContext.SaveChanges();

These roles get added to the aspnetRoles Table correctly.

Then in my AccountController for Internal users I use the Register Post action:

            var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };
            result = await UserManager.CreateAsync(user, model.Password);

            if (result.Succeeded)
            {
                UserManager.AddToRole(user.Id, "Internal");
                string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
...

Which adds a record to the aspnetUsers table, and another to the aspnetUserRoles table with the User ID matching the new user and the Role ID matching the corresponding role.

I then do the same for my External registrations:

public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
    if (User.Identity.IsAuthenticated)
    {
        return RedirectToAction("Index", "Manage");
    }
    if (ModelState.IsValid)
    {
        // Get the information about the user from the external login provider
        var info = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            return View("ExternalLoginFailure");
        }
        var user = new ApplicationUser { UserName = model.userName, Email = model.Email };
        var result = await UserManager.CreateAsync(user);
        if (result.Succeeded)
        {
            UserManager.AddToRole(user.Id, "External");
            result = await UserManager.AddLoginAsync(user.Id, info.Login);
            if (result.Succeeded)
            {
                await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                return RedirectToLocal(returnUrl);
            }
        }
        AddErrors(result);
    }
    ViewBag.ReturnUrl = returnUrl;
    return View(model);
}

Which does exactly the same thing, creates the user in the DB and adds matching IDs to the UserRoles table.

However, when I log in using either method and try to navigate to an action with [Authorize(Roles="Internal")] or [Authorize(Roles="External")] I cannot access them. I added a test using ApplicationUser CurrentUser = UserManager.FindByName("MyUserName"); which successfully returns my user from the database, but when I then say Console.WriteLine(CurrentUser.Roles); the CurrentUser.Roles has a count of 0, which makes it look like the role was not assigned correctly.

Is there something I have missed in the assigning role process? I cannot figure it out.

Thanks.

Edit Answer / Further question...

When adding the users to roles using the above, the users id is added to the UserId column of the UserRoles table, but there was a third column called IdentityUser_Id which was always null.

Out of curiosity I added my user id to that column as well and now the everything works. the application picked up my user role.

My follow up question to this is can I set the IdentityUser_Id automatically? using something similar to the UserManager.AddToRole() which adds the userId to both columns?

thanks

Jake
  • 1,207
  • 2
  • 28
  • 46
  • Your project may be also using the legacy role manager functionality. Try addin `....` into your `web.config`. – DavidG May 19 '15 at 23:28
  • Under ``? I also noticed it has this: `` is that right? It is a standard MVC5 project with Individual User Accounts – Jake May 19 '15 at 23:35
  • That's something different and not related to Identity. Did disabling the role manager help? – DavidG May 19 '15 at 23:36
  • Ok, No it did not, the `UserManager.GetRoles()` still returns 0 and `User.IsInRole("Internal")` returns false – Jake May 19 '15 at 23:38

1 Answers1

0

Here is what my similar code looks like. I use the role manager to create the roles:

            var roleStore = new RoleStore<IdentityRole>(db);
            var roleManager = new RoleManager<IdentityRole>(roleStore);
            var userStore = new UserStore<ApplicationUser>(db);
            var userManager = new UserManager<ApplicationUser>(userStore);

            // Add missing roles
            var role = roleManager.FindByName("External");
            if (role == null)
            {
                role = new IdentityRole("External");
                roleManager.Create(role);
            }
            role = roleManager.FindByName("Internal");
            if (role == null)
            {
                role = new IdentityRole("Internal");
                roleManager.Create(role);
            }

            // Create test users
            var user = userManager.FindByName("admin");
            if (user == null)
            {
                var newUser = new ApplicationUser()
                {
                    UserName = "admin",
                    FirstName = "Admin",
                    LastName = "User",
                    Email = "xxx.xxx@xxx.net",
                    PhoneNumber = "5555559492",
                    MustChangePassword = false
                };
                userManager.Create(newUser, "Password1");
                userManager.SetLockoutEnabled(newUser.Id, false);
                userManager.AddToRole(newUser.Id, "Internal");
            }
            user = userManager.FindByName("limited");
            if (user == null)
            {
                var newUser = new ApplicationUser()
                {
                    UserName = "limited",
                    FirstName = "Limited",
                    LastName = "User",
                    Email = "limited@mypd.com",
                    PhoneNumber = "6085555556",
                    MustChangePassword = false
                };
                userManager.Create(newUser, "Password1");
                userManager.SetLockoutEnabled(newUser.Id, false);
                userManager.AddToRole(newUser.Id, "External");
            }
Steve Greene
  • 12,029
  • 1
  • 33
  • 54
  • Thanks, But I copy/pasted your code exactly and am getting the same thing. Users and Roles are created in the database, but when you add a `user.Roles` line and break on it `user.Roles` contains 0. – Jake May 20 '15 at 21:34
  • See if you have a rolemanager reference in web.config. Shouldn't need anything in there with identity 2. – Steve Greene May 21 '15 at 13:34