I am using Active Directory to authen开发者_StackOverflow中文版ticate users for an intranet site. I would like to refine the users that are authenticated based on the group they are in in Active Directory. Can someone show me or point me to directions on how to find what groups a user is in in ASP.NET 4.0 (VB)?
I realize this post is quite old but I thought I might update it with processes I am using. (ASP.Net 4.0, VB)
If using integrated windows security, on a domain.
Page.User.IsInRole("domain\GroupName")
will check to see if the authenticated user is a member of the specified group.
If you would like to check another users group membership other than the authenticated user.
Two stage for checking multiple groups with the same user principal:
Dim MyPrincipal As New System.Security.Principal.WindowsPrincipal _
(New System.Security.Principal.WindowsIdentity("UserID"))
Dim blnValid1 As Boolean = MyPrincipal.IsInRole("domain\GroupName")
Single stage for checkin a single group:
Dim blnValid2 As Boolean = New System.Security.Principal.WindowsPrincipal _
(New System.Security.Principal.WindowsIdentity("userID")).IsInRole("domain\GroupName")
NOTE:: The IsInRole method does work with nested groups. If you have a top level group with a sub group that is a member, and the user is a member of the sub group.
I think I have the ultimate function to get all AD groups of an user included nested groups without explicit recursion:
Imports System.Security.Principal
Private Function GetGroups(userName As String) As List(Of String)
Dim result As New List(Of String)
Dim wi As WindowsIdentity = New WindowsIdentity(userName)
For Each group As IdentityReference In wi.Groups
Try
result.Add(group.Translate(GetType(NTAccount)).ToString())
Catch ex As Exception
End Try
Next
result.Sort()
Return result
End Function
So just use GetGroups("userID"). Because this approach uses the SID of the user, no explicit LDAP call is done. If you use your own user name it will use the cached credentials and so this function is very fast.
The Try Catch is necessary because in large companyies the AD is so big that some SIDs are getting lost in space.
For those who may be interested, this is how I ended up coding it:
Dim ID As FormsIdentity = DirectCast(User.Identity, FormsIdentity)
Dim ticket As FormsAuthenticationTicket = ID.Ticket
Dim adTicketID As String = ticket.Name
Dim adSearch As New DirectorySearcher
adSearch.Filter = ("(userPrincipalName=" & adTicketID & ")")
Dim adResults = adSearch.FindOne.Path
Dim adResultsDirectory As New DirectoryEntry(adResults)
Dim found As Boolean = False
For Each entry In adResultsDirectory.Properties("memberOf")
Response.Write(entry)
Response.Write("<br/>")
If entry = "CN=GroupName,CN=UserGroup,DC=my,DC=domain,DC=com" Then
found = True
End If
Next
If Not (found) Then
Response.Redirect("login.aspx")
End If
I found this here.
''' <summary>
''' Function to return all the groups the user is a member od
''' </summary>
''' <param name="_path">Path to bind to the AD</param>
''' <param name="username">Username of the user</param>
''' <param name="password">password of the user</param>
Private Function GetGroups(ByVal _path As String, ByVal username As String, _
ByVal password As String) As Collection
Dim Groups As New Collection
Dim dirEntry As New _
System.DirectoryServices.DirectoryEntry(_path, username, password)
Dim dirSearcher As New DirectorySearcher(dirEntry)
dirSearcher.Filter = String.Format("(sAMAccountName={0}))", username)
dirSearcher.PropertiesToLoad.Add("memberOf")
Dim propCount As Integer
Try
Dim dirSearchResults As SearchResult = dirSearcher.FindOne()
propCount = dirSearchResults.Properties("memberOf").Count
Dim dn As String
Dim equalsIndex As String
Dim commaIndex As String
For i As Integer = 0 To propCount - 1
dn = dirSearchResults.Properties("memberOf")(i)
equalsIndex = dn.IndexOf("=", 1)
commaIndex = dn.IndexOf(",", 1)
If equalsIndex = -1 Then
Return Nothing
End If
If Not Groups.Contains(dn.Substring((equalsIndex + 1), _
(commaIndex - equalsIndex) - 1)) Then
Groups.Add(dn.Substring((equalsIndex + 1), & _
(commaIndex - equalsIndex) - 1))
End If
Next
Catch ex As Exception
If ex.GetType Is GetType(System.NullReferenceException) Then
MessageBox.Show("Selected user isn't a member of any groups " & _
"at this time.", "No groups listed", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
'they are still a good user just does not
'have a "memberOf" attribute so it errors out.
'code to do something else here if you want
Else
MessageBox.Show(ex.Message.ToString, "Search Error", & _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Try
Return Groups
End Function
End Class
To just check if a user is member of a group including sub-groups just use:
Public Function IsInGroup(ByVal objectName As String, groupName As String) As Boolean
Try
return New WindowsPrincipal(New WindowsIdentity(objectName)).IsInRole(groupName))
Catch ex As Exception
End Try
Return False
End Function
精彩评论