【问题标题】:Get all groups for a user using LDAP使用 LDAP 获取用户的所有组
【发布时间】:2014-04-09 12:52:48
【问题描述】:

我已尝试从 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 获取用户的所有组?

【问题讨论】:

  • 使用PrincipalContextUserPrincipal 的第一种方法在幕后使用LDAP - 那么你想通过使用旧式的、遗留的第二种方法来实现什么?您希望从中获得什么好处?
  • 好吧,不知道 PrincipalContext 也使用 LDAP。我可以使用 LDAP 语法和 PrincipalContext 连接到目录吗?例如:服务器名:myServer 端口:389 DC=example,DC=com
  • 如果您需要了解此类信息 - 您应该始终想一想:MSDN 在线文档!。查看MSDN docs on PrincipalContext and the availanle constructor overloads - 它们允许您指定要连接的服务器和域,以及要使用的凭据(如果需要)
  • 我查看了 MSDN 文档。但我仍然不知道如何连接到以下 LDAP: ldap.andrew.cmu.edu 我试过了: using (var domainContext = new PrincipalContext(ContextType.Domain, "ldap.andrew.cmu.edu", " cn=log"))
  • 或任何其他无 AD 服务器(OpenLDAP 和 co)

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


【解决方案1】:

我的第一个建议是你应该拆分你的方法,以便更好地了解:

  1. 获取您的用户。

你可以使用类似的东西:

/// <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. 获取其所有组。

使用第二种方法来清楚简单地获取组。

/// <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();
}

path 是您的 OU 路径(根或非根)。

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

希望对你有所帮助。

【讨论】:

    【解决方案2】:

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

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2017-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多