MVC 5 AddToRole requires logout before it works?

2019-01-14 08:47发布

问题:

I'm finding that if I add a user to a role in ASP Identity, it doesn't take effect until I log out and log back in. Is there something I need to do to refresh a user's roles without forcing a user to log off first?

Here's how I'm adding the user to the role.

var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var userId = HttpContext.Current.User.Identity.GetUserId();

userManager.AddToRole(userId, roleName);

Then, almost immediately, I redirect the user to this action method. I can tell in the database that I've been added to the correct role, but MVC still redirects me to the login page. However, if I log out, log back in, and attempt to go to this action method, it works just fine.

    [Authorize(Roles = RecoveryStandardRoles.ServiceProvider)]

    public partial class CertifyController : Controller

{
    #region Public Methods and Operators

    public virtual ActionResult CompanyProfile()
    {
        return this.View();
    }

    #endregion
}

Thank you for taking time to look at my question!

回答1:

MVC5 register new user, assign role and activate user with role WITHOUT logging off and back on by using :await UserManager.AddToRoleAsync(user.Id, "Role Name")

if (ModelState.IsValid)
{
    var user = new ApplicationUser() { UserName = model.Email, Email = model.Email,StandName = model.StandName,FirstName = model.FirstName,LastName = model.LastName,CellPhone = model.CellPhone,Supervisor = model.Supervisor};
    IdentityResult result = await UserManager.CreateAsync(user, model.Password);

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

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


    if (result.Succeeded)
    {
         ***await UserManager.AddToRoleAsync(user.Id, "Users Tammy");***
         await SignInAsync(user, isPersistent: false);


回答2:

@kevin-junghans your answer lead me to the correct answer. This code shows how to add a user to a role in MVC 5 and to have that role automatically take effect.

var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var userId = HttpContext.Current.User.Identity.GetUserId();

userManager.AddToRole(userId, roleName);

var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;

authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

var user = userManager.FindById(userId);
var identity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);

authenticationManager.SignIn(new AuthenticationProperties { IsPersistent = false }, identity);


回答3:

ASP.NET Identity uses claims to store the roles and uses the claims instead of doing a database query each time it needs to perform authorization. So the roles will not be in the claims until the person has been logged in again. You can read about using claims in ASP.NET Identity here. The articles shows how to add claims during the log-in process. But if you add a role to the current user you can update the claims using the method described in my answer to this QA without forcing the user to log in again. There is a claim for each role assigned to the user. Use ClaimTypes.Role when adding a new role.



回答4:

After adding a role to the current user you can update the claims without forcing the user to log off and log in again.

Dim owinAuth = HttpContext.Current.GetOwinContext().Authentication
Dim authResult = Await owinAuth.AuthenticateAsync(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie)

authResult.Identity.AddClaim(New System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Role, "RoleName"))

Equivalent C# code for reference:

var owinAuth = HttpContext.Current.GetOwinContext().Authentication;

var authResult =
    await owinAuth.AuthenticateAsync(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);

authResult.Identity.AddClaim(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Role, roleName));