2015-02-06 85 views
3

我不知道我是否在这里失去了一些东西。默认User.IsInRole()不起作用,即使用户有一定的作用。如何在Asp.net Identity 3.0和MVC 6中启用角色?

我没有自己的角色商店的实现。我假设默认的应该工作。在Startup.cs中我需要做些什么特殊的工作才能让角色工作?我正在使用mvc 6 beta 2默认模板。

回答

1

User.IsInRole()如果我添加这样的角色不起作用:

await UserManager.AddToRoleAsync(user, "Admin");

但它确实工作,如果我这样做:

await UserManager.AddClaimAsync(user, claim: new Claim(ClaimTypes.Role.ToString(), "Admin"));

+0

我想你也正等待AddToRoleAsync电话吗? – 2015-02-06 20:30:01

+0

AddToRoleAsync调用的结果是什么? – 2015-02-10 01:37:53

0

它看起来像你使用Asp.NET Identity和最新的ASP.NET 5东西。我使用相同的(目前使用RC1)。我有一个类似的问题,经过一些挖掘,我找到了一个解决方案,使用SignInManagerRefreshSignInAsync()方法。

注意,得到的UserManagerSignInManager我使用依赖注入一个实例的保持,所以我的控制器的构造是这样的:

public MyController(
    UserManager<ApplicationUser> userManager, 
    SignInManager<ApplicationUser> signInManager) 
{ 
    _userManager = userManager; 
    _signInManager = signInManager; 
} 

我的要求是,如果一个特定的控制器方法被访问通过身份验证的用户,如果用户尚未拥有该角色,则该角色将被添加到该用户,并且需要立即生效。 (后续调用控制器和视图中的User.IsInRole("TheRole")需要返回true,而用户不必注销并返回)。

这里的行动:

[AllowAnonymous] 
    public async Task<IActionResult> CreateProfile() 
    { 
     if (User == null || User.Identity == null || !User.Identity.IsAuthenticated) 
     { 
      return RedirectToAction("RegisterOrSignIn", "Account"); 
     } 
     else 
     { 
      if (!User.IsInRole("TheRole")) 
      { 
       ApplicationUser applicationUser = 
        await _userManager.FindByIdAsync(User.GetUserId()); 
       await _userManager.AddToRoleAsync(applicationUser, "TheRole"); 
       await _signInManager.RefreshSignInAsync(applicationUser); 
      } 
      return RedirectToAction("Index"); 
     } 
    } 

注意你需要

using System.Security.Claims; 

GetUserId()扩展方法。

所以我学到的大事是用UserManagerAddToRoleAsyncSignInManagerRefreshSignInAsync。第一个添加一行到AspNetUserRoles表。第二个刷新cookie,用来自浏览器的下一个请求将显示该用户在角色中。

另外,我在Startup.cs中添加了一个名为EnsureRoles()的方法。我打电话给app.UseIdentity()拨打电话Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)。所以,这里是从Configure()一个snipit:

... 

    // Add cookie-based authentication to the request pipeline. 
    app.UseIdentity(); 

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed 
    // Ensure roles are in DB - OK not to await this for now 
    EnsureRoles(app, loggerFactory); 
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed 

    ... 

这里是EnsureRoles()

private async Task EnsureRoles(IApplicationBuilder app, ILoggerFactory loggerFactory) 
{ 
    ILogger logger = loggerFactory.CreateLogger<Startup>(); 
    RoleManager<IdentityRole> roleManager = app.ApplicationServices.GetService<RoleManager<IdentityRole>>(); 

    string[] roleNames = { "TheRole", "AnotherRole" }; 

    foreach (string roleName in roleNames) 
    { 
     bool roleExists = await roleManager.RoleExistsAsync(roleName); 
     if (!roleExists) 
     { 
      logger.LogInformation(String.Format("!roleExists for roleName {0}", roleName)); 
      IdentityRole identityRole = new IdentityRole(roleName); 
      IdentityResult identityResult = await roleManager.CreateAsync(identityRole); 
      if (!identityResult.Succeeded) 
      { 
       logger.LogCritical(
        String.Format(
         "!identityResult.Succeeded after 
         roleManager.CreateAsync(identityRole) for 
         identityRole with roleName {0}", 
         roleName)); 
       foreach (var error in identityResult.Errors) 
       { 
        logger.LogCritical(
         String.Format(
          "identityResult.Error.Description: {0}", 
          error.Description)); 
        logger.LogCritical(
         String.Format(
          "identityResult.Error.Code: {0}", 
         error.Code)); 
       } 
      } 
     } 
    } 
} 
相关问题