2013-12-10 18 views
11

我发现如果我将用户添加到ASP身份中的某个角色,直到我注销并重新登录后才会生效。是否需要执行某些操作来刷新用户的角色而不强制用户先注销?MVC 5 AddToRole在它工作之前需要注销?

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

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 
} 

谢谢你花时间看我的问题!

+1

如果你检查,如果有人在你的代码的作用,'User.IsInRole(角色名)'需要注销和登录,以反映被添加到新的角色。 'UserManager.IsInRole(userID,roleName)'不。 – nmit026

回答

7

MVC5通过使用注册新用户,分配角色和激活与角色用户而不注销,然后再打开:等待UserManager.AddToRoleAsync(user.Id, “角色名称”)

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

这个答案帮助我解决了这个问题。我有一行将用户添加到**线后的角色**。一旦我在**登录之前添加角色**,角色就会添加,而不需要签出/签入。 – hatmatbbat10

+0

创建问题后的几年中,这是我使用最多的答案。关键是确保你有'AddToRoleAsync' _before_'SignInAsync' –

5

ASP.NET身份使用声明来存储角色,并使用声明而不是在每次需要执行授权时执行数据库查询。所以这些角色将不会出现在索赔中,直到该人再次登录。你可以阅读约using claims in ASP.NET Identity here。这些文章显示了如何在登录过程中添加声明。但是,如果您将角色添加到当前用户,则可以更新声明using the method described in my answer to this QA而不强制用户再次登录。有分配给用户的每个角色的声明。添加新角色时使用ClaimTypes.Role。

+0

这没有意义,因为我的索赔表中没有任何内容。 AddUserToRole为AspNetUserRoles添加记录,AspNetUserClaims中没有任何记录。你能解释一下吗? –

+0

另外,您引用的答案中的AuthenticationManager.SignIn行不能编译。 –

+1

我所指的索赔不在数据库表中。他们在CurrentPrincipal中。 –

6

@ 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); 
+1

您正在有效地将人员记录下来并重新登录,这将起作用。方法CreateIdentity将再次添加角色作为声明,有效地添加新角色。我所描述的方法可能会回答您并不需要再次查询数据库来填充这些声明。 –

2

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

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