【问题标题】:How to turn on Roles in Asp.net Identity 3.0 and MVC 6?如何在 Asp.net Identity 3.0 和 MVC 6 中打开角色?
【发布时间】:2015-02-06 00:43:24
【问题描述】:

我不确定我是否在这里遗漏了什么。默认情况下,即使用户拥有某些角色,User.IsInRole() 也不起作用。

我没有自己的角色存储实现。我假设默认的应该可以工作。我需要在Startup.cs 中做一些特别的事情来让这些角色发挥作用吗?我正在使用 mvc 6 beta 2 默认模板。

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我假设您也在等待 AddToRoleAsync 调用?
    • AddToRoleAsync 调用的结果是什么?
    【解决方案2】:

    看起来您正在使用带有最新 ASP.NET 5 内容的 Asp.NET Identity。我正在使用相同的(当前使用 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() 的方法。我在Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 中调用app.UseIdentity() 后立即调用它。所以,这是来自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));
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-26
      • 2022-11-23
      • 2013-11-10
      • 2016-10-24
      • 1970-01-01
      • 2014-10-28
      • 1970-01-01
      • 2015-05-19
      相关资源
      最近更新 更多