.net 有没有办法让UserPrincipal.GetGroups()和UserPrincipal.GetAuthorizationGroups()调用使用LDAP(端口636)而不是LDAP(端口389)?
我们正在为微软3月份的AD更新做准备,只允许使用LDAP进行安全调用,在检查.Net代码时,我发现对UserPrincipal.GetGroups()和UserPrincipal.GetAuthorizationGroups()的调用似乎使用LDAP(端口389)而不是LDAP(端口636),即使UserPrincipal对象是使用在LDAP上建立的PrincipalContext创建的,如下所示:.net 有没有办法让UserPrincipal.GetGroups()和UserPrincipal.GetAuthorizationGroups()调用使用LDAP(端口636)而不是LDAP(端口389)?,.net,active-directory,ldap,active-directory-group,.net,Active Directory,Ldap,Active Directory Group,我们正在为微软3月份的AD更新做准备,只允许使用LDAP进行安全调用,在检查.Net代码时,我发现对UserPrincipal.GetGroups()和UserPrincipal.GetAuthorizationGroups()的调用似乎使用LDAP(端口389)而不是LDAP(端口636),即使UserPrincipal对象是使用在LDAP上建立的PrincipalContext创建的,如下所示: // Explicitly using LDAPS (port 636) Pri
// 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();
有人知道为什么会发生这种情况吗?如果有,如何强制这些呼叫使用LDAP?如果他们不能被强制执行,有什么解决方法吗?这肯定是.NET代码中的一个错误,我会回答你的问题,但正如我在你的另一个问题中提到的,三月更新将不会“只允许使用LDAP进行安全呼叫”。更新后,389的普通LDAP端口仍将工作。我没有看到任何证据表明他们曾计划禁用它 但是,如果您想确保它无论如何都不会使用端口389,那么您将没有not not use
UserPrincipal
。直接使用DirectoryEntry
和/或DirectorySearcher
,这正是UserPrincipal
在后台使用的。这不在AccountManagement
命名空间中
我写了一篇关于的文章,其中有一些针对不同场景的示例代码。您必须修改创建新的DirectoryEntry
对象并指定端口636的任何情况,如下所示:
new DirectoryEntry("LDAP://example.com:636/CN=whatever,DC=example,DC=com")
如果您愿意,您实际上可以省略域名(只需:636
而不是example.com:636
)
我在那篇文章中没有提到的一个案例相当于GetAuthorizationGroups
,即读取tokenGroups
属性。这将为您提供组的SID列表,然后您可以查找该列表以查找组的名称。这里有一个方法可以做到这一点:
私有静态IEnumerable GetTokenGroup(DirectoryEntry de){
var-groupsFound=0;
//仅从用户检索tokenGroups属性
de.RefreshCache(新[]{“tokenGroups”});
while(true){
var tokenGroups=de.Properties[“tokenGroups”];
foreach(令牌组中的字节[]groupSidByte){
groupsFound++;
var groupSid=新的SecurityIdentifier(groupSidByte,0);
var groupDe=newdirectoryEntry($“LDAP://:{de.Options.PasswordPort}/”;
groupDe.RefreshCache(新[]{“cn”});
收益率返回(字符串)groupDe.Properties[“cn”].Value;
}
//AD一次只能提供1000或1500(取决于服务器版本)
//如果我们找到了,去看看还有没有
如果(tokenGroups.Count!=1500&&tokenGroups.Count!=1000)中断;
试一试{
de.RefreshCache(新[]{$”memberOf;范围={groupsFound}-*“});
}捕获(COMException e){
如果(e.ErrorCode==unchecked((int)0x80072020))中断;//没有更多结果
投掷;
}
}
}
它将使用用于创建传入的
DirectoryEntry
对象的任何端口。但是,如果您的环境中有多个域,则这会中断。如果您想始终使用636端口,那么在这种情况下事情可能会变得复杂。谢谢,Gabriel!我尝试了代码,但它找不到像GetAuthorizationGroups那样多的组。试图找到一条共同的线索。额外的组都是本地的内置组(所有人、管理员、性能日志用户、经过身份验证的用户、此组织、安全声明的身份和高强制级别)。我读了你的文章,但我没有注意到任何可能的罪魁祸首。我们只有一个域,没有受信任的外部域。有什么想法吗?我给的代码只会返回广告组。你提到的那些群体不是广告群体。他们不是(像每个人)就是本地团体。现有的每个帐户都将被视为所有人的一部分。本地组将根据运行此代码的计算机而更改。这是您实际需要的吗?如果您想为当前用户(代码运行的用户)执行此操作,您可以调用并查看属性。奇怪的是,您的代码返回“Users”,它似乎是一个已知的SID(s-1-5-32-545)。事实上,如果您查看此列表,它会将其中的每一个列为组、别名、帐户或内置组。运行whoami/groups
会显示相同的结果。我认为我们不需要这些团体,但我不能确定。我正在排除故障的代码是由其他人生成的,我对它或AD的了解还不够。不幸的是,我正在排除故障的代码没有使用当前用户,因此我无法使用WindowsIdentity.GetCurrent()
。顺便说一句,我喜欢你的文章。他们的信息量很大!