如何在Asp.net Identity 3.0和MVC 6中打开角色?

时间:2015-02-06 00:43:25

标签: asp.net-core asp.net-core-mvc asp.net-identity-3

我不确定我是否遗漏了一些东西。默认情况下User.IsInRole()即使用户具有某些角色也不起作用。

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

2 个答案:

答案 0 :(得分:2)

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

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

但如果我这样做,它确实有效:

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

答案 1 :(得分:0)

您似乎正在使用Asp.NET Identity和最新的ASP.NET 5。我使用相同的(目前使用RC1)。我遇到了类似的问题,经过一番挖掘后,我使用SignInManager RefreshSignInAsync()方法找到了解决方案。

请注意,要获取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()扩展方法。

所以我学到的重要事情是使用UserManager AddToRoleAsyncSignInManager&#39; s RefreshSignInAsync。第一行向AspNetUserRoles表添加一行。第二个刷新cookie,使用浏览器的下一个请求,将显示用户在角色中。

顺便说一句,我在Startup.cs中添加了一个名为EnsureRoles()的方法。我在app.UseIdentity()致电Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)后立即致电。所以,这里是来自Configure()的片段:

    ...

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