我有一个我创建的简单角色提供程序。 (所以表格认证)。
当放置在页面上时,内置在asp.net登录控件中的标准可以正常工作。
我试图确定为什么标准的“测试”角色会被视为失败。
到目前为止,我有这个:
Roles.Provider.IsUserInRole(Membership.GetUser.UserName,“Portal”)返回true
Roles.IsUserInRole(Membership.GetUser.UserName,“Portal”)返回false
为什么第二种格式失败? (注意下面的IsInRole代码是由上面的两个人调用的!!)。
User.IsInRole(“Portal”)返回false。
那么,在3个例子中,只有一个有效吗?
有人建议为什么User.IsInRole()不起作用?
请注意,User.IsInRole()由于某种原因不会调用以下例程,但上面的两个代码都会这样做。
Public Overrides Function IsUserInRole(username As String, roleName As String) As Boolean
Dim rst As DataTable
Dim strSql As String
MsgBox("Is user in Role test")
strSql = "SELECT Email, RoleName FROM dbo_ContactName " & _
"LEFT JOIN Web_UsersInRoles ON Web_usersInRoles.User_ID = dbo_ContactName.Id " & _
"LEFT JOIN Web_Roles on Web_Roles.ID = Web_UsersInRoles.Role_ID " & _
"WHERE Email = '" & username & "' and RoleName = '" & roleName & "'"
rst = Myrst(strSql)
If rst.Rows.Count > 0 Then
Return True
Else
Return False
End If
End Function
请注意,MOST令人困惑的是:
Roles.IsUserInRole(Membership.GetUser.UserName,“Portal”)返回false
我已经验证上面导致我的自定义代码运行但总是返回false。
实际上如果我硬代码上面的例程返回“true”,那么上面的#2 STILL调用我的代码并且STILL返回false !!!
这么大的问题: 即使硬编码上面的例程总是返回true,为什么这种格式会失败?
Roles.IsUserInRole(Membership.GetUser.UserName,“Portal”)
更糟糕的是,为什么这会失败?
User.IsInRole(“Portal”)再次返回false。
那么我应该寻找哪些设置来启用2和3?
总结:
1 - Roles.Provider.IsUserInRole(Membership.GetUser.UserName,“Portal”)返回true
2 - Roles.IsUserInRole(Membership.GetUser.UserName,“Portal”)返回false
3 - User.IsInRole(“Portal”)返回false
4 - User.Identity.Name返回正确的登录用户kallal@msn.com
我还可以验证从上面#3 NEVER调用IsUserInRole代码。这包括在清晰的浏览器缓存之后。
快速的BinGoolge显示,在采用自定义角色提供程序时,大量人员发现User.IsInRole()停止工作。在编写导致此失败的自定义角色提供程序时,必须存在一些“重要”问题。
关于如何获得2或3个以上选项的链接或建议非常受欢迎。
使用Visual Studio 2013,并使用vb.net创建标准的asp.net网站(框架工作4.5)
编辑: 作为后续行动,所有我的角色功能都有效。
例如: Roles.GetAllRoles() - 这可行(返回所有角色正确)
Roles.GetRolesForUser() - this works, retruns all roles for CURRENT user
Roles.GetUserInRole("Portal") - this works, returns all users in role group "portal"
不工作:
User.IsInRole("Portal") - as noted 1000's of posts on internet have this issue!
Roles.IsUserInRole(Membership.GetUser.UserName, "Portal")
以下是我未包含在原始帖子中的其他潜艇:
Public Overrides Function GetUsersInRole(roleName As String) As String()
Dim rst As DataTable
Dim i As Integer
Dim a As New List(Of String)
Dim strSql As String
MsgBox("get users in role code")
strSql = "SELECT Email, RoleName FROM dbo_ContactName " & _
"LEFT JOIN Web_UsersInRoles ON Web_usersInRoles.User_ID = dbo_ContactName.Id " & _
"LEFT JOIN Web_Roles on Web_Roles.ID = Web_UsersInRoles.Role_ID " & _
"WHERE RoleName = '" & roleName & "' " & _
"ORDER BY Web_Roles.RoleName"
rst = Myrst(strSql)
For i = 0 To rst.Rows.Count - 1
a.Add(rst.Rows(i).ItemArray(0).ToString)
Next
Return a.ToArray
End Function
Public Overrides Function GetRolesForUser(username As String) As String()
Dim rst As DataTable
Dim i As Integer
Dim a As New List(Of String)
Dim strSql As String
strSql = "SELECT Email, RoleName FROM dbo_ContactName " & _
"LEFT JOIN Web_UsersInRoles ON Web_usersInRoles.User_ID = dbo_ContactName.Id " & _
"LEFT JOIN Web_Roles on Web_Roles.ID = Web_UsersInRoles.Role_ID " & _
"WHERE Email = '" & username & "' " & _
"ORDER BY Web_Roles.RoleName"
rst = Myrst(strSql)
For i = 0 To rst.Rows.Count - 1
a.Add(rst.Rows(i).ItemArray(1).ToString)
Next
Return a.ToArray
End Function
Public Overrides Function GetAllRoles() As String()
Dim rst As DataTable
Dim i As Integer
Dim a As New List(Of String)
rst = Myrst("select RoleName from Web_Roles order by RoleName")
For i = 0 To rst.Rows.Count - 1
a.Add(rst.Rows(i).ItemArray(0).ToString)
Next
Return a.ToArray
End Function
以上所有功能都有效。
问题仍然存在:
我们如何连接到User.IsInRole()的ENABLE使用。 Thiis不起作用。
总结如下:
Roles.GetRolesForUser - returns "current" roles for user - works fine
Roles.GetUsersInRole("Portal") - works fine
Roles.GetAllRoles() - works fine.
User.IsInRole() - BROKEN!
更多摘要:这是一些带有结果输出的代码:
Debug.WriteLine(Roles.Provider.IsUserInRole(Membership.GetUser.UserName, "Portal"))
Debug.WriteLine(Roles.IsUserInRole(Membership.GetUser.UserName, "Portal"))
Debug.WriteLine(User.Identity.Name)
Debug.WriteLine(User.Identity.IsAuthenticated)
Debug.WriteLine(User.IsInRole("Portal"))
输出:
Roles.Provider.IsUserInRole = True
Roles.IsUserInRole = False
User.Identity.Name = kallal@msn.com
User.Identity.IsAuthenticated = True
User.IsInRole("Portal") = False < -- still broken!!!
答案 0 :(得分:2)
您需要在自定义提供程序中实现GetRolesForUser
。
当您在当前用户的ASP.NET应用程序中呼叫Roles.IsUserInRole
时,它会调用System.Web.Security.RolePrincipal.IsUserInRole
。
RolePrincipal.IsUserInRole
将在首次访问时调用角色提供程序的GetRolesForUser
方法,并在内部缓存角色列表。它实际上从未调用过提供程序的IsUserInRole
方法。
令人困惑的是,当您在WCF应用程序中使用ASP.NET角色时,它的工作方式不同(principalPermissionMode =&#34; UseAspNetRoles&#34;)。在这种情况下,它不使用System.Web.Security.RolePrincipal
类,而是使用内部类System.ServiceModel.Security.RoleProviderPrincipal
。
RoleProviderPrincipal.IsUserInRole
将调用角色提供程序的IsUserInRole
方法,并且不会尝试缓存当前用户的角色列表。
两种不同的实现具有不同的性能特征。
ASP.NET方法(GetRolesForUser然后在内部缓存角色)意味着即使在处理请求期间多次调用IsUserInRole,也只有一次调用提供程序。但是对于某些提供商(例如WindowsTokenRoleProvider
),getting the list of all roles can be expensive, resulting in poor performance。
WCF方法(每次调用提供程序的IsUserInRole方法)可能导致在处理单个请求期间多次调用提供程序。但是,除非明确请求,否则永远不会检索当前用户的完整角色列表,这可以为WindowsTokenRoleProvider
等提供商提供更好的性能,而这些提取的代价很高。
答案 1 :(得分:1)
这里概述了解决这个难以捉摸的问题的方法:
HttpContext.Current.User.IsInRole not working
海报的答案和后续内容载于评论部分。
建议的解决方案是在角色名称上放置一个trim()。完成CODE STARTED工作后!
角色名称有一个尾随空格,作为一个远景,我在为用户加载角色的代码上放置了一个修剪,并确保代码开始工作。既然已经修剪了提供角色的原始数据,那么现在有问题的代码可以正常工作。
我不能赞成这个解决方案,但是这个问题和问题的链接包含在上面。
因此,由于某些角色名称的尾随空白,此代码(以及其他经过测试的代码)失败了。
最有意思的是
Roles.Provider.IsUserInRole(Membership.GetUser.UserName, "Portal")
以上作品!有尾随空格
Roles.IsUserInRole(Membership.GetUser.UserName, "Portal")
上面不适用于尾随空格
User.IsInRole("Portal")
上面不适用于尾随空格。
所以这里的巨大提示是Roles.Provider.IsUserInRole(Membership.GetUser.UserName,“Portal”)确实有效!如果其他人失败,那么REST保证你的角色名称中存在杂散空间的问题。
删除了杂散空间后,现在所有情况下的所有上述例子都可以正常工作。
答案 2 :(得分:0)
谢谢Joe - &gt; &#34; User.IsInRole&#34;在用户通过身份验证之后才会工作
为我解决了显示什么时候的问题!在_Layout.cshtml中
@if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.IsInRole("Manager"))
{
@Html.Partial("_ManageNav")
}
if (HttpContext.Current.User.IsInRole("Administrator"))
{
@Html.Partial("_ManageNav")
}
}
仅显示&#34; _ManageNav&#34;如果为用户分配了管理员或管理员角色
不适用于组合字符串(&#34; Manager,Administrator&#34;)
不能用于组合字符串(&#34;经理&#34;,&#34;管理员&#34;)