在 Java 的 Active Directory 林中工作时如何将域名转换为 LDAP DC?
我正在努力解决一个问题,无法找到精益且通用的解决方案。这是我的情况:
我在一个巨大的AD森林中,> 20 个子域在数百台服务器上进行复制。假设主域和 Kerberos 领域是 COMPANY.COM
,而我在 D1.COMPANY.COM
中工作。 我确实从 Java 连接到全局目录,并且能够访问整个 forrest 以支持所有公司用户。
我的连接 URL 如下所示: ldap://mycompany.com:3268/DC=company,DC=com
整个内容在使用 SPNEGO 的 Web 应用程序中运行,以对用户进行身份验证,效果非常好。即,成功登录后,我确实收到了用户 UPN/Kerberos 主体。由于某些原因,林中的所有 UPN 字段都会更改为匹配用户的电子邮件地址,而不是保持 UPN 值不变。这意味着我无法通过 krb princ 进行搜索,但我必须删除用户名并通过 sAMAccountName
进行搜索。 我认为 sAMAccountName
在整个林中是唯一的,直到昨天用户登录失败。经过一些 LDAP 查询魔法后,我发现两个用户在两个不同的域中具有相同的 sAMAccountName
。我的搜索失败了。
所以问题是,如何确定基于 Kerberos 领域的领域/子域的基本 DN/DC?
我想出了几种使用剥离领域字符串的方法:
- 构建 LDAP URL 并连接到并读取 defaultNamingContext
- 将域名重新格式化为 DC=d1,DC...
目前,我正在使用方法 2,这似乎是最简单的方法。尽管这里关于堆栈溢出的一些 C# 帖子表示这可能会由于不相交的空格而失败。
有人知道安全的解决方案吗?实际上,最好的方法是将 Kerberos 主体转换为用户主体名称。
I am struggling with a problem where I wasn't able to find a lean and generic solution. This is my situation:
I am in a huge AD forest with > 20 sub domains replicating over several hundreds servers. Say the main domain and Kerberos realm is COMPANY.COM
and I am working in D1.COMPANY.COM
.
I do connect from Java to the global catalog and are able to access the entire forrest to support all company users.
My connection URL is like this: ldap://mycompany.com:3268/DC=company,DC=com
The entire stuff is running in a webapp using SPNEGO to authenticate the users which works very well. I.e., after sucessful login I do receive the users UPN/Kerberos principal. Due to some reasons all UPN fields in the forest where altered to match user's email address rather to leave the UPN value intact. This means that I an not able to search for the search by the krb princ but I have to strip out the username and search by sAMAccountName
.
I presumed the sAMAccountName
is unique in the entire forest until a user failed to login yesterday. After some LDAP query magic I figured out that two users have the same sAMAccountName
in two different domains. My search fails.
So the issue is, how do I determine the base DN/DC of a realm/sub domain based in the Kerberos realm?
I figured out several approaches with a stripped realm string:
- constuct an LDAP URL and connect to and read defaultNamingContext
- reformat domain name to DC=d1,DC...
Currently, I am using approach 2 which seems to be the easiest way. Altough some C# post here on stack overflow said that this might fail due to disjoint spaces.
Is anyone aware of a safe solution? The best would be actually to translate Kerberos principals to user principal names.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
登录后,您会收到 UPN,这是一封电子邮件。可以使用它的用户名部分,因为它不是唯一的。不能使用域部分,因为它需要与命名上下文相同。您可能有 dc=mydomain,dc=com,但电子邮件的域可能类似于 myemaildomain.com。我也可以将其添加为附加 UPN,我想这就是您的案例中发生的情况。
不要采取第二种方法。拿第一个。
执行 dns srv 查找 _ldap._tcp.domain.com
阅读DnsQueryConfig以获取配置的域名
获取服务器名称。
执行 rootDse 搜索请求namingContext。
并构建 ldapurls
进一步...,
看起来您域中的 emailid 在整个森林中是唯一的(?)
如果是这样,您可以将电子邮件 ID 标记为 PAS 属性,以便每个 GC 都有它的副本,并在 GC 端口上执行 ldap 搜索电子邮件 ID。但这是一个非常糟糕的选择,因为这也需要对 20 多个子域进行架构更改。
After login you get the UPN which is a email. The username part of it can be used because its not unique. The domain part can not be used because it need to be same as naming context. You may have the dc=mydomain,dc=com but the domain for the email can be like myemaildomain.com. And I can add this as additional UPN as well, i guess this is what happened in your case.
Do not take the second approach. Take the first one.
Do a dns srv lookup _ldap._tcp.domain.com
Read about DnsQueryConfig to get the configured domain name
Get the server name.
do a rootDse search requesting namingContext.
and construct the ldapurls
Further..,
it looks like the emailid in your domain is unique across the forest (?)
If so, may be you can mark the email id as PAS attribute so that every GC has the copy of it and do a ldap search on the GC port for emailid. But this is a very bad option as this requires schema changes that too with more than 20 subdomains.
Kaylan,oVirt 项目 (www.ovirt.org) 包含 Spring-Ldap 代码,该代码向您展示如何使用 Kerberos 针对 Active-Directory、RHDS、ipa 和 Tivoli-DS 进行身份验证。我们仍然需要继续并实现森林功能(刚刚为此询问了有关 Java 中 CLdap 实现的问题)。为了获得defaultNamingContext,您必须向所需的域发出RootDSE 查询(我们在oVirt 中也有一些代码)。
您可以通过执行 git clone 下载源代码,也可以使用 http://gerrit.ovirt.org 浏览它们
请查看 engine\backend\manager\modules\bll\src\main\java\org\ovirt\engine\core\bll\adbroker 下的代码,
您将在其中看到所需的一切。
Kaylan, the oVirt project (www.ovirt.org) contains Spring-Ldap code that shows you how to authenticate with Kerberos against Active-Directory, RHDS, ipa, and Tivoli-DS. We still need to continue and implement forest functionality (Just asked a question about CLdap implementation in Java for that). In order to get defaultNamingContext you will have to issue a RootDSE query (we have some code for that as well in oVirt) to the desired domain.
You can download the sources by performing git clone, or you can browse them using http://gerrit.ovirt.org
Please look at the code under engine\backend\manager\modules\bll\src\main\java\org\ovirt\engine\core\bll\adbroker
You will see there all you need for your this.