有没有一种方法可以使UserPrincipal.GetGroups()和UserPrincipal.GetAuthorizationGroups()调用使用LDAPS(端口636)而不是LDAP(端口389)?

问题描述 投票:1回答:1

[我们正在为Microsoft的三月AD更新做准备,以仅允许使用LDAPS进行安全调用,并且在检查.Net代码时,我发现对UserPrincipal.GetGroups()和UserPrincipal.GetAuthorizationGroups()的调用似乎使用LDAP(端口389)而不是LDAPS(端口636),即使UserPrincipal对象是使用通过LDAPS建立的PrincipalContext创建的,也是如此:

    // Explicitly using LDAPS (port 636)
    PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, "our.corpdomain.com:636", "DC=our,DC=corpdomain,DC=com", ContextOptions.Negotiate);
    UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, "someuser");

    // These calls still use LDAP (port 389)
    var groups = userPrincipal.GetAuthorizationGroups();
    var groups2 = userPrincipal.GetGroups();

有人知道为什么会发生这种情况吗,如果发生这种情况,如何强制这些调用使用LDAPS?如果不能强迫他们,是否有解决方法?

.net active-directory ldap active-directory-group
1个回答
0
投票
这肯定是.NET代码中的错误,我会回答您的问题,但是就像您在其他问题中提到的那样,三月的更新不会“仅允许使用LDAPS进行安全调用”。在该更新之后,普通的LDAP端口389仍然可以使用。我没有看到任何证据表明他们打算禁用它。

但是,如果要确保它永远不会使用端口389,就不会使用UserPrincipal。直接使用DirectoryEntry和/或DirectorySearcher,无论如何,这都是UserPrincipal在后台使用的内容。这不是the first bug I've found名称空间中的AccountManagement

我写了一篇有关finding all of a user's groups的文章,其中包含一些针对不同情况的示例代码。您将必须修改创建新DirectoryEntry对象并指定端口636的任何情况,例如:

new DirectoryEntry("LDAP://example.com:636/CN=whatever,DC=example,DC=com")

您实际上可以根据需要省略域名(只是:636而不是example.com:636)。

[我在那篇文章中没有提到的一种情况与GetAuthorizationGroups等效,即读取tokenGroups属性。这为您提供了组的SID列表,然后您可以查找这些列表以查找组的名称。这是一种可以做到这一点的方法:

private static IEnumerable<string> GetTokenGroups(DirectoryEntry de) { var groupsFound = 0; //retrieve only the tokenGroups attribute from the user de.RefreshCache(new[] {"tokenGroups"}); while (true) { var tokenGroups = de.Properties["tokenGroups"]; foreach (byte[] groupSidByte in tokenGroups) { groupsFound++; var groupSid = new SecurityIdentifier(groupSidByte, 0); var groupDe = new DirectoryEntry($"LDAP://:{de.Options.PasswordPort}/<SID={groupSid}>"); groupDe.RefreshCache(new[] {"cn"}); yield return (string) groupDe.Properties["cn"].Value; } //AD only gives us 1000 or 1500 at a time (depending on the server version) //so if we've hit that, go see if there are more if (tokenGroups.Count != 1500 && tokenGroups.Count != 1000) break; try { de.RefreshCache(new[] {$"memberOf;range={groupsFound}-*"}); } catch (COMException e) { if (e.ErrorCode == unchecked((int) 0x80072020)) break; //no more results throw; } } }

这将使用您用于创建传入的DirectoryEntry对象的任何端口。但是,如果您的环境中有多个域,则此操作将中断。如果要始终使用端口636,在这种情况下事情可能会变得复杂。
© www.soinside.com 2019 - 2024. All rights reserved.