首先,我为我糟糕的英语道歉。我是巴西人,所以如果案文中有任何错误,请不要理会。 p>
我在这里阅读了很多关于检索属性的文章" unicodePwd"在Active Directory中,但实际上都没有帮助我。
那么,为什么我需要这些信息呢?我将解释:
我这里有一些java例程,它们将来自不同系统的用户信息统一起来。 此例程获取主Oracle数据库中所需的信息,并在另一个数据库(基本上是Oracle和MySQL)中设置信息。
例如:我们有一个私有云系统,运行在CentOS Linux操作系统中,拥有自己的MySQL数据库。为了统一用户信息,包括用户密码,我们从主Oracle数据库获取信息并设置执行此系统的MySQL数据库,以统一用户详细信息和登录信息。
我在这里的所有惯例都在运作,没有问题,但现在我们遇到了新的挑战。
我们需要与我们的Active Directory用户进行相同的统一,获取此主Oracle数据库所需的信息,然后将所有信息设置为Active Directory用户,包括用户密码。
我已经在Active Directory用户中成功更新了密码,但我不希望每次运行此java例程时密码都会更新,但只有在主Oracle数据库中密码更改时才会更新。
示例:当其中一个用户更改主Oracle数据库中的密码时,java例程会将此用户信息设置为在Active Directory中的同一用户中设置。为了做到这一点,例程在Active Diretory中获取相同的信息,然后它比较两个密码(Oracle的密码和Active Diretory的密码),最后,如果密码不同,例程将更新它,但如果密码没有什么不同,例程将什么也不做。
这就是为什么我需要检索属性" unicodePwd"在Active Directory中。
以下是我的一些代码:
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import org.apache.commons.mail.EmailException;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
public class ldapQuery {
String distinguishedName = "";
String department = "";
String physicalDeliveryOfficeName = "";
String telephoneNumber = "";
String mobile = "";
String title = "";
String sAMAccountName = "";
String unicodePwd = "";
public ldapQuery(String mail) {
try {
final Hashtable<String, String> env = new Hashtable<String, String>();
final String adminName = "CN=MY DOMAIN ADMIN,CN=MY DOMAIN ADMIN FOLDER LOCALIZATION,DC=MY DOMAIN,DC=MY DOMAIN,DC=MY DOMAIN";
final String adminPasswd = "MY DOMAIN ADMIN PASSWORD";
final String ldapUrl = "ldaps://MY ACTIVE DIRECTORY SERVER:636";
final String factory = "com.sun.jndi.ldap.LdapCtxFactory";
final String authType = "simple";
final String protocol = "ssl";
env.put(Context.INITIAL_CONTEXT_FACTORY, factory);
env.put(Context.SECURITY_AUTHENTICATION, authType);
env.put(Context.SECURITY_PRINCIPAL, adminName);
env.put(Context.SECURITY_CREDENTIALS, adminPasswd);
env.put(Context.SECURITY_PROTOCOL, protocol);
env.put(Context.PROVIDER_URL, ldapUrl);
DirContext ctx = new InitialLdapContext (env,null);
SearchControls searchCtls = new SearchControls();
String returnedAtts[] = {"sAMAccountName", "distinguishedName","department", "physicalDeliveryOfficeName", "telephoneNumber", "mobile", "title", "unicodePwd"};
searchCtls.setReturningAttributes(returnedAtts);
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String searchFilter = "(&(objectClass=user)(mail=" + mail +"))";
String searchBase = "DC=MY DOMAIN,DC=MY DOMAIN,DC=MY DOMAIN";
int totalResults = 0;
NamingEnumeration<SearchResult> answer =ctx.search(searchBase, searchFilter, searchCtls);
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult)answer.next();
totalResults++;
Attributes attrs = sr.getAttributes();
if (attrs != null) {
distinguishedName = (String) attrs.get("distinguishedName").get();
department = (String) attrs.get("department").get();
physicalDeliveryOfficeName = (String) attrs.get("physicalDeliveryOfficeName").get();
telephoneNumber = (String) attrs.get("telephoneNumber").get();
mobile = (String) attrs.get("mobile").get();
title = (String) attrs.get("title").get();
sAMAccountName = (String) attrs.get("sAMAccountName").get();
Attribute passwd = attrs.get("unicodePwd");
unicodePwd = unicodePwd + passwd;
if (department == null) {
department = "";
}
if (physicalDeliveryOfficeName == null) {
physicalDeliveryOfficeName = "";
}
if (telephoneNumber == null) {
telephoneNumber = "";
}
if (mobile == null) {
mobile = "";
}
if (title == null) {
title = "";
}
}
}
}
catch (NamingException e){
System.err.println("FAIL MESSAGE: " + e);
}
}
public String ldapSearchResultDistinguishedName() {
return distinguishedName;
}
public String ldapSearchResultDepartment() {
return department;
}
public String ldapSearchResultPhysicalDeliveryOfficeName() {
return physicalDeliveryOfficeName;
}
public String ldapSearchResultTelephoneNumber() {
return telephoneNumber;
}
public String ldapSearchResultMobile() {
return mobile;
}
public String ldapSearchResultTitle() {
return title;
}
public String ldapSearchResultUnicodePwd() {
return unicodePwd;
}
public String ldapSearchResultSAMAccountName() {
return sAMAccountName;
}
}
运行代码后,所有变量都会返回正确的信息,但变量&#34; unicodePwd&#34;,即使用户有密码,也会返回&#34; null&#34 ;.
我知道字节UTF-16LE的事情和&#34; unicodePwd&#34; Active Directory中的字段是加密的,但正如我之前解释的那样,我需要在String变量中解密信息。
任何想法?
谢谢!
答案 0 :(得分:1)
我知道这是一个古老的问题,但是我偶然发现了这个问题,因为我也在寻找相同问题的答案。我找到了答案,并认为这可能对落在这里的其他人有所帮助。
根据Microsoft Documentation,似乎LDAP搜索从不返回unicodePwd属性。
就我而言,我需要验证收到的凭据是否正确。因此,我的计划是使用收到的用户名/密码,并使用这些凭据即时创建自定义LdapContextFactory。如果我可以通过执行LdapContextFactory.get成功地与服务器联系并获取LdapContext,则可以确定提供的密码是正确的。如果您不找回它,那您就知道它是错误的,可以从那里拿走。