【问题标题】:MVC 5 AddToRole requires logout before it works?MVC 5 AddToRole 需要注销才能工作?
【发布时间】:2013-12-28 00:22:58
【问题描述】:

我发现如果我将用户添加到 ASP 身份中的角色,它在我注销并重新登录之前不会生效。我需要做些什么来刷新用户的角色而不强制用户先注销?

以下是我将用户添加到角色的方式。

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

userManager.AddToRole(userId, roleName);

然后,几乎立即,我将用户重定向到此操作方法。我可以在数据库中知道我已被添加到正确的角色,但 MVC 仍将我重定向到登录页面。但是,如果我注销、重新登录并尝试使用此操作方法,它就可以正常工作。

    [Authorize(Roles = RecoveryStandardRoles.ServiceProvider)]

    public partial class CertifyController : Controller

{
    #region Public Methods and Operators

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

    #endregion
}

感谢您花时间查看我的问题!

【问题讨论】:

  • 如果您要检查是否有人在您的代码中担任某个角色,User.IsInRole(roleName) 需要注销并登录以反映被添加到新角色。 UserManager.IsInRole(userID, roleName) 没有。

标签: asp.net-mvc-5 asp.net-identity


【解决方案1】:

MVC5 注册新用户,分配角色并激活具有角色的用户,无需注销并使用 :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);

【讨论】:

  • 这个答案帮助我解决了这个问题。我有一行将用户添加到角色之后要登录的行。一旦我添加了角色之前登录,该角色被添加而无需注销/in.
  • 创建问题多年后,这是我使用最多的答案。关键是确保你AddToRoleAsync 之前 SignInAsync
【解决方案2】:

@kevin-junghans 你的回答引导我找到正确的答案。此代码显示如何在 MVC 5 中将用户添加到角色并让该角色自动生效。

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);

【讨论】:

  • 您正在有效地将该人注销并重新登录,这将起作用。 CreateIdentity 方法将再次将角色添加为声明,从而有效地添加新角色。我在可能回答中描述的方法不需要您再次查询数据库来填写这些声明。
【解决方案3】:

ASP.NET Identity 使用声明来存储角色并使用声明而不是每次需要执行授权时都进行数据库查询。因此,在此人再次登录之前,这些角色不会出现在声明中。您可以阅读有关using claims in ASP.NET Identity here 的信息。文章展示了如何在登录过程中添加声明。但是,如果您向当前用户添加角色,您可以更新声明using the method described in my answer to this QA,而无需强制用户再次登录。分配给用户的每个角色都有一个声明。添加新角色时使用 ClaimTypes.Role。

【讨论】:

  • 这没有意义,因为我的索赔表中没有任何内容。 AddUserToRole 向 AspNetUserRoles 添加一条记录,并且 AspNetUserClaims 中没有任何内容。你能解释一下吗?
  • 我所指的声明不在数据库表中。它们在 CurrentPrincipal 中。
  • 我遇到的问题是当我,应用程序的管理员(从我自己的计算机)手动添加一个不同的用户(他自己已经从他自己的计算机登录!)到角色...此用户可能会保持登录状态 14 天(默认)并且在他决定注销并重新登录之前看不到新角色...我想我需要添加自定义代码来检测“每次都查询数据库,然后执行已经给出的建议?
  • @Funka - 他们添加了一种更有效的方法来处理这个问题,这在 ASP.NET Identity 2.0 中更受事件驱动。您要使用的是 SecurityStamp。看看这个QA。 stackoverflow.com/questions/19487322/…
  • @KevinJunghans 您能否发布一个专门适用于这种情况的代码示例。我们将不胜感激,因为您显然对索赔了解很多。
【解决方案4】:

向当前用户添加角色后,您可以更新声明,而无需强制用户注销并重新登录。

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"))

等效的C#代码供参考:

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));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多