【问题标题】:User.IsInRole doesn't workUser.IsInRole 不起作用
【发布时间】:2013-03-12 03:10:32
【问题描述】:

我有 ASP.NET MVC 4 应用程序。我使用 Simple Membership Provider 允许勾选登录表单下的记住我复选框。如果勾选,将创建持久性 cookie .ASPXAUTH,自登录日期起 100 天后过期。除了应用程序的主菜单外,一切正常。

菜单的某些部分仅供管理员用户使用。我用:

@if (User.IsInRole("Administrator")) { @Html.Partial("_MainMenuPartial") }

锁定它们,使其不被呈现给普通用户。这种方法在登录系统后就可以正常工作。当我在一段时间后返回并使用持久 cookie 对我进行身份验证时,我确实登录了,但是

@User.IsInRole("Administrator")

返回“False”,所以我看不到管理菜单项。同时

@User.Identity.Name

返回正确的登录名和

@User.Identity.IsAuthenticated

返回“True”,证明持久 cookie 工作正常。为什么即使用户经过系统验证,我也无法访问用户角色?

【问题讨论】:

  • 您是如何实际创建角色的?什么时候真正为用户分配角色 - 在您的注册 ActionResult 中?
  • 是的,这就是我在注册操作中的做法:Roles.AddUsersToRoles(new[] { model.UserName }, new[] { role });而角色是之前确定的字符串。
  • 一种更安全的方法是在 InitialiseSimpleMembershipAttribute.cs 类中:在 Websecurity.InitialiseDatabaseConnection 下方使用 if (!Roles.RoleExists("Admin")) Roles.CreateRole("Admin");。您是否尝试使用我在回答中描述的重载方法。
  • 我发现这个问题的解决方案是在 App_Start 文件夹的 FilterConfig 类的 RegisterGlobalFilters 方法中添加一个过滤器。有关详细信息,请参阅此:stackoverflow.com/questions/16215316/…

标签: asp.net-mvc forms-authentication simplemembership .aspxauth


【解决方案1】:

清除所有 cookie 并尝试再次登录。如果我们改变了我们的角色,cookie 可能不会意识到这一点。重置 Cookie 并使用您的新角色创建一个 cookie,然后重试。

【讨论】:

    【解决方案2】:

    可能会发生一些事情,以下是一些一般性的尝试:

    1. 尝试在调试模式下运行并确保代码行得到执行 - 很傻,但可能会发生
    2. 如其他答案所述,请尝试注销并重新登录
    3. 确保角色拼写正确
    4. 确保为正确的用户分配了正确的角色 ID
    5. 尝试将整个解决方案重新发布到服务器 - 在我的情况下,一切都在本地运行良好,但在服务器上没有,直到完全删除并重新发布
    6. 如果一切都失败了,请尝试运行一个现成的项目并在增加复杂性之前对其进行测试

    【讨论】:

      【解决方案3】:

      如果您使用 Brock Allen 的 IdentityManager 创建角色并将其分配给用户,那么您应该阅读这篇文章:https://github.com/IdentityManager/IdentityManager.AspNetIdentity/issues/3

      您需要取消注释以下行:

      this.RoleClaimType = System.Security.Claims.ClaimTypes.Role;
      

      现在您会意识到,您以前在角色中的用户已不在其中,您必须重新添加它们。如果您查看 AspNetUserClaims 表,您将看到角色的 claimType 和您想要的“http://schemas.microsoft.com/ws/2008/06/identity/claims/role”。

      执行此操作后,User.IsInRole("rolename") 将按预期运行。

      我希望这对某人有所帮助,我花了一段时间才弄清楚这一点。

      【讨论】:

      • 发生这种情况是因为默认情况下IdentityManager.Configuration.SecurityConfiguration.RoleClaimType 设置为Constants.ClaimTypes.Role,即设置为“角色”,而System.Security.Claims.ClaimsPrincipal.IsInRole(string role) 设置为HasClaim(m_identities[i].RoleClaimType, role),其中RoleClaimType 是“schemas.microsoft.com/ws/2008/06/identity/claims/role”。您的修复(有效)的问题是,一个人将无法再在 UI 中使用声明“角色”,而必须使用那个长字符串。
      【解决方案4】:

      将此代码粘贴到 Global.asax

      protected void Application_AuthenticateRequest(Object sender, EventArgs e)
              {
                  HttpCookie authCookie =
                      Context.Request.Cookies[FormsAuthentication.FormsCookieName];
                  if (authCookie != null)
                  {
                      FormsAuthenticationTicket authTicket =
                          FormsAuthentication.Decrypt(authCookie.Value);
                      string[] roles = authTicket.UserData.Split(new Char[] { ',' });
                      GenericPrincipal userPrincipal =
                          new GenericPrincipal(new GenericIdentity(authTicket.Name), roles);
                      Context.User = userPrincipal;
                  }
              }
      
              protected class RolesAttribute : AuthorizeAttribute
              {
                  public RolesAttribute(params string[] roles)
                  {
                      Roles = String.Join(",", roles);
                  }
              }
      

      【讨论】:

        【解决方案5】:

        如果您使用的是最新的身份框架,请查看您是否使用以下

        services.AddIdentity<IdentityUser,IdentityRole>()
                .AddEntityFrameworkStores<WebUserContext>()
                .AddDefaultTokenProviders();
        

        如果您使用的是 AddDefaultIdentity,则不会填充角色。

        services.AddDefaultIdentity<IdentityUser>()
                .AddEntityFrameworkStores<WebUserContext>()
                .AddDefaultTokenProviders();
        

        【讨论】:

        • 谢谢。这是最新的答案。
        【解决方案6】:

        这些答案都不适合我,但我确实在这里找到了答案:https://thinkthencode.wordpress.com/2016/04/24/azure-ad-using-app-roles-for-authorization/

        关键是将以下内容添加到Startup.Auth.cs

        TokenValidationParameters = new TokenValidationParameters
        {
            RoleClaimType = "roles"
        }
        

        【讨论】:

          【解决方案7】:

          老问题,但这里缺少一些信息。我遇到了同样的问题,还有一件事要记住。如果您在验证后(不向客户端发送响应)测试用户身份(像 User.IsInRole("admin")),身份框架没有填充此会话信息(或者至少,我找不到这样做的方法)。您请求的此信息会在您的控制器返回后的某个时间点填充。如果您希望(I.E.)在登录后重定向到不同的视图,根据用户角色,您必须使用自定义授权过滤器。

          【讨论】:

          • 是的,我所做的是在登录后重定向到另一个页面。然后我可以在该页面上获取用户的角色。
          【解决方案8】:

          一段时间以来,我一直在为 MVC5 角色管理器而苦苦挣扎。我已经验证User.IsInRole 可以同时返回不同的结果,显然这是因为User 对象被缓存了,需要失效。一种方法是注销并重新登录,作为此处指定的答案之一。只需将其放入添加新角色的控制器中即可:

                  UserManager.AddToRole(User.Identity.GetUserId(), "Administrator");
          
                  var updatedUser = await UserManager.FindByNameAsync(User.Identity.Name);
                  var newIdentity = await updatedUser.GenerateUserIdentityAsync(UserManager);
                  AuthenticationManager.SignOut();
                  AuthenticationManager.SignIn(newIdentity);
          

          但是,如果用户在其他窗口中打开了您的应用程序,则不会更新所有窗口。

          【讨论】:

            【解决方案9】:

            这个账号的“EmailConfirmed”可能还是假的,试试改成真

            【讨论】:

            • 这对我有用
            【解决方案10】:

            在用户前面添加页面。这有效:Page.User.IsInRole("Administrator")

            【讨论】:

              【解决方案11】:

              相当老的话题,但可以在 vs 2015 Web 表单应用程序工作解决方案中确认:

              <modules>
                  <remove name="FormsAuthenticationModule" />
                  <remove name="RoleManager" /> <!--add this to web config-->
              </modules>
              

              【讨论】:

                【解决方案12】:

                在 MVC5 中使用角色的问题

                我找到了解决方案。在我的 web.config 中:

                <modules>
                    <remove name="FormsAuthenticationModule" />
                    <remove name="RoleManager" />
                </modules>
                

                我添加了 remove name="RoleManager" 行,并且新的 AspNet.Identity 代码接管了允许我使用 User.IsInRole(..)

                http://forums.asp.net/t/1952572.aspx?Problem+using+roles+with+MVC5

                【讨论】:

                • 是的,在 Win10 上的 VS2015 中工作(当它在另一台机器上没有问题时。谢谢!
                • 它也对我有用,但我担心删除 RoleManager 的后果是什么。起初我的网站看起来不错,但我不知道什么时候应该担心(我刚刚删除了哪些其他功能)。有人吗?
                • 我尝试了很多其他方法。但最后这对我有用
                【解决方案13】:

                对于我的代码,它必须是复数,而不是单数:

                User.IsInRole("Administrators")
                

                【讨论】:

                • 这个答案并不相关——仅仅因为字符串值不同并不能证明另一个答案是正确的
                • 这可能会帮助您了解与此处匹配的角色字符串需要在您的数据库中的Name 列中的默认AspNetRoles 表设置中完成的条目
                【解决方案14】:

                我有一个 smilar 问题。就我而言,当我注销并再次登录时,问题就解决了。

                【讨论】:

                【解决方案15】:

                你有没有尝试添加

                [InitializeSimpleMembership]
                

                在您进行检查的控制器中?

                【讨论】:

                • 我遇到了同样的问题,这为我解决了问题。
                【解决方案16】:

                IsUserInRole 返回 false 时遇到了类似的问题。通过将手表放在上面,我能够通过使用下面描述的过载来克服这个问题。试一试,在错误的地方设置一个断点,看看会发生什么。

                @if (Roles.IsUserInRole(Model.UserName, "Administrator"))
                

                我很确定您也可以使用User.Identity.Name 作为第一个参数。

                【讨论】:

                  【解决方案17】:

                  我遇到了类似的问题,但在我的情况下,问题是会话超时未与身份验证超时同步,因此我没有被自动踢出,但我的会话已过期,并且由于我允许的操作存储在会话变量,我无法为当前用户检索正确的选项。

                  即使您仍处于登录状态,也请尝试检查您的会话是否未过期

                  【讨论】:

                  • 我并没有真正在应用程序中的任何地方使用会话变量。
                  【解决方案18】:

                  我遇到了类似的问题,好像身份验证模块没有与 SimpleMembershipProvider 完全连接。为了解决这个问题,您可以使用 Role 类来访问所需的信息。例如要检查角色中的使用,您可以使用以下内容:

                  Roles.GetRolesForUser("sergey").Contains("Developer")
                  

                  在使用 SimpleMembershipProvider 角色时还有其他有用的方法:

                     Roles.RoleExists("Developer")
                     Roles.CreateRole("Developer");
                     Roles.AddUserToRole("sergey", "Developer");
                  

                  【讨论】:

                  • 不幸的是,您的解决方案对我不起作用:alert("@User.IsInRole("Administrator")"); alert("@Roles.GetRolesForUser(User.Identity.Name).Contains("Administrator")");两者都返回 False
                  • 您能否尝试查看该用户是否有任何角色? string.Join(",", Roles.GetRolesForUser(User.Identity.Name))
                  • alert("@string.Join(",", Roles.GetRolesForUser(User.Identity.Name))");返回空字符串
                  • 你知道你的用户有角色吗?尝试先使用 Roles.CreateRole("Developer"); 分配角色Roles.AddUserToRole("sergey", "开发者");然后检查角色是否存在。祝你好运。
                  • 正如我之前提到的,角色是存在的。如果我退出并重新登录,我将被识别为“管理员”。只是当我在一段时间后返回应用程序并通过cookie角色进行身份验证时神奇地消失了。
                  猜你喜欢
                  • 2016-02-29
                  • 2015-11-06
                  • 2019-03-06
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-04-14
                  • 2017-08-20
                  • 1970-01-01
                  相关资源
                  最近更新 更多