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