How to translate a domain name to LDAP DC when working in a Active Directory forest in Java?
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开发者_Python百科 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.
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, 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.
精彩评论