使用LDAP获取用户的所有组

时间:2014-04-09 12:52:48

标签: c# active-directory ldap active-directory-group

我尝试从LDAP加载用户的所有组。

目前我在我们当地的AD上进行测试。使用以下代码,我可以加载给定用户的所有组:

public IEnumerable<String> GetUserGroups( String userName )
{ 
    using ( var domainContext = new PrincipalContext( ContextType.Domain, Name ) )
    {
        var user = UserPrincipal.FindByIdentity( domainContext, userName );
        return user.GetAuthorizationGroups().Select( x => x.Name} ).ToList();
    }
}

但是我无法使用LDAP获得相同的结果。

使用LDAP的代码:

public IEnumerable<String> GetUserGroups1(String userName)
{
    //returns the container name of the given user
    var containerName = GetUserContainerName(userName); 
    var groups = new List<String>();
    if (containerName == null)
        return groups;

    var entry = new DirectoryEntry(String.Format("LDAP://{0}", "DC=example,DC=com"));

    var searcher = new DirectorySearcher(entry)
    {
        Filter = String.Format("(member:{0}:=CN={1},{2},{3})",
                               "1.2.840.113556.1.4.1941",
                               containerName, "CN=Users", "DC=example,DC=com"),
        SearchScope = SearchScope.Subtree
    };

    var result = searcher.FindAll();
    for (var i = 0; i < result.Count; i++)
    {
        var path = result[i].Path;
        var startIndex = path.IndexOf("CN=", StringComparison.Ordinal) + 3;
        groups.Add(path.Substring(startIndex, path.IndexOf(",", startIndex + 1,
                   StringComparison.Ordinal) - startIndex));
     }
     return groups;
}

如何使用LDAP获取用户的所有组?

2 个答案:

答案 0 :(得分:2)

我的第一个建议是,您应该将方法拆分为更好的概述:

  1. 获取您的用户。
  2. 你可以使用类似的东西:

    /// <summary>
    /// Return the user by the user name
    /// </summary>
    /// <param name="userName_">Username to base search on</param>
    /// <returns>
    /// User Manager or null if not found
    /// </returns>
    public static DirectoryEntry SearchForUser(string userName_)
    {
        DirectoryEntry de = null;
        DirectorySearcher directorySearcher = null;
        Domain domain = null;
        try
        {
            if (String.IsNullOrEmpty(userName_))
                return null;
    
            string userName = userName_.StartsWith("CN=") ? userName_.Replace("CN=", String.Empty) : userName_;
    
            de = new DirectoryEntry("LDAP://" + Domain.GetCurrentDomain().Name);
            directorySearcher = new DirectorySearcher(de);
            directorySearcher.Filter = string.Format("(&(objectClass=person)(objectCategory=user)(sAMAccountname={0}))", userName);
            SearchResult searchResult = directorySearcher.FindOne();
    
            return searchResult != null ? searchResult_.GetDirectoryEntry() : null;
        }
        finally
        {
            if (de != null)
                de.Dispose();
            if (directorySearcher != null)
                directorySearcher.Dispose();
            if (domain != null)
                domain.Dispose();
        }
    }
    

    这样,您就可以验证LDAP路径,域名,域

    1. 获取所有群组。
    2. 使用第二种方法清楚简单地获取群组。

      /// <summary>
      ///Returns a list with the groups where this user is a member of. 
      /// </summary>
      /// <remarks>The members in the returned list are instances of Group.</remarks>
      /// <returns>Groups where this user is member of.</returns>
      public List<DirectoryEntry> GetGroups()
      {
          return (from object o in Entry.Properties["memberOf"]
                  select new DirectoryEntry(path)
                  into dirEntry
                  where dirEntry.SchemaClassName == "group"
                  select {DirectoryEntry = dirEntry}).ToList();
      }
      

      路径是您的OU路径(根或不)。

      最大的挑战是管理和构建LDAP路径。

      我希望有所帮助。

答案 1 :(得分:1)

我最终得到了这段代码。 它返回包含给定用户的每个组的名称。

private IEnumerable<String> GetGroupsOfUser( String userName )
{
    var groupNames = new List<String>();

    // Open a LDAP connection
    using ( var ldapConnection = OpenLdapConnection() )
    {
        // Configuration (should work for an AD with default settings):
        // MemberOfAttributeKey => "memberOf"
        // UserFilterDn => "DC=domain1,DC=domain2,DC=domain3"
        // UserFilter => "(&(objectCategory=person)(sAMAccountName={0}))"
        // ProtocolVersion => 3


        // Search for the user data in the directory
        var ldapFilter = SecurityConfiguration.LdapConfiguration.UserFilter.F( userName );
        String[] attributesToReturn = { SecurityConfiguration.LdapConfiguration.MemberOfAttributeKey };
        var searchRequest = new SearchRequest( SecurityConfiguration.LdapConfiguration.UserFilterDn,
                                                ldapFilter,
                                                SearchScope.Subtree,
                                                attributesToReturn );

        // Check if the response is valid
        var searchResponse = ldapConnection.SendRequest( searchRequest ) as SearchResponse;
        if ( searchResponse?.Entries?.Count != 1 )
            throw new DirectoryException( "Invalid search response received from the directory." );

        var entry = searchResponse.Entries[0];
        if ( !entry.Attributes.Contains( SecurityConfiguration.LdapConfiguration.MemberOfAttributeKey ) )
            Logger.Warn( "Entry does not contain a member of attribute." );
        else
            for ( var index = 0; index < entry.Attributes[SecurityConfiguration.LdapConfiguration.MemberOfAttributeKey]
                                                .Count; index++ )
            {
                // Extract the group name
                var groupName = entry.Attributes[SecurityConfiguration.LdapConfiguration.MemberOfAttributeKey][index]
                                        .ToString();
                var name = groupName.Substring( 3, Math.Min( groupName.IndexOf( ",", StringComparison.InvariantCultureIgnoreCase ) - 3, groupName.Length - 3 ) );
                groupNames.Add( name );
            }
    }

    return groupNames;
}

private LdapConnection OpenLdapConnection()
{
    // Use the server name and port to setup an LDAP Directory Service
    var directoryIdentifier = new LdapDirectoryIdentifier( SecurityConfiguration.LdapConfiguration.Server, SecurityConfiguration.LdapConfiguration.Port );
    var ldapConnection = new LdapConnection( directoryIdentifier );

    // Set the protocol version
    ldapConnection.SessionOptions.ProtocolVersion = SecurityConfiguration.LdapConfiguration.ProtocolVersion;

    // If user name parameter present set connection credentials
    if ( SecurityConfiguration.LdapConfiguration.UserName.IsNotEmpty() )
    {
        // Set connection credentials
        var networkCredential = new NetworkCredential( SecurityConfiguration.LdapConfiguration.UserName,
                                                        SecurityConfiguration.LdapConfiguration.Password );

        if ( SecurityConfiguration.LdapConfiguration.UserDomain.IsNotEmpty() )
            networkCredential.Domain = SecurityConfiguration.LdapConfiguration.UserDomain;
        ldapConnection.Credential = networkCredential;

        // Set connection authentication type
        ldapConnection.AuthType = SecurityConfiguration.LdapConfiguration.AuthType;
    }

    // Connection establishment
    ldapConnection.Bind();

    return ldapConnection;
}