我尝试从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获取用户的所有组?
答案 0 :(得分: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路径,域名,域
使用第二种方法清楚简单地获取群组。
/// <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;
}