And*_*ser 14 java ldap active-directory unboundid-ldap-sdk
我正在研究一种从AD获取用户详细信息并将其导入另一个系统的工具.我们计划使用objectSid作为唯一标识符,但我发现由于某种原因,LDAP结果中的objectSid与Active Directory中的对象不匹配.大多数字节都是相同的,但有些字节有所不同,有时LDAP结果的字节数比AD中的字节少.
AD中用户的objectSid:
decimal: [ 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 35, 106, 222, 96, 236, 251, 239, 68, 32, 255, 234, 203, 122, 4, 0, 0]
hex: [01, 05, 00, 00, 00, 00, 00, 05, 15, 00, 00, 00, 23, 6A, DE, 60, EC, FB, EF, 44, 20, FF, EA, CB, 7A, 04, 00, 00]
Run Code Online (Sandbox Code Playgroud)
通过LDAP结果为同一用户提供objectSid:
decimal: [ 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 35, 106, 63, 96, 63, 63, 63, 68, 32, 63, 63, 63, 122, 4, 0, 0]
hex: [01, 05, 00, 00, 00, 00, 00, 05, 15, 00, 00, 00, 23, 6A, 3F, 60, 3F, 3F, 3F, 44, 20, 3F, 3F, 3F, 7A, 04, 00, 00]
Run Code Online (Sandbox Code Playgroud)
看起来似乎任何超过128的值都会在LDAP结果中返回为63/3F.对于另一个用户,LDAP结果缺少1个字节(问号):
hex from AD: [01 05 00 00 00 00 00 05 15 00 00 00 23 6A DE 60 EC FB EF 44 20 FF EA CB 88 04 00 00]
hex from LDAP: [01 05 00 00 00 00 00 05 15 00 00 00 23 6A 3F 60 3F 3F 3F 44 20 3F 3F 3F ?? 04 00 00]
Run Code Online (Sandbox Code Playgroud)
这是我用来进行这些测试的代码的主要部分.
final String ldapADServer = "ldap://" + cmdLine.getOptionValue("ldap");
final String bindDN = cmdLine.getOptionValue("u");
final String bindCredential = cmdLine.getOptionValue("p");
final String baseCtxDN = cmdLine.getOptionValue("d");
final Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, bindDN);
env.put(Context.SECURITY_CREDENTIALS, bindCredential);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapADServer);
env.put("com.sun.jndi.ldap.trace.ber", System.err);
final LdapContext ctx = new InitialLdapContext(env, null);
final String searchFilter = "(&(objectClass=user) (sAMAccountName=" + accountName + "))";
final SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
final StringBuilder builder = new StringBuilder();
final NamingEnumeration<SearchResult> results = ctx.search(baseCtxDN, searchFilter, searchControls);
while (results != null && results.hasMoreElements()) {
final SearchResult result = results.nextElement();
builder.append(LdapHelper.getSearchResultDetails(result, ""));
}
logger.info("Search results: {}{}", StringUtils.NEW_LINE, builder.toString());
Run Code Online (Sandbox Code Playgroud)
LdapHelper只是循环遍历所有属性,并以格式良好的字符串返回它们.objectGUID和objectSid以十六进制格式打印.
我使用JRE 6和JRE 7运行测试,结果相同.我们的AD服务器是Window Server 2008 RC2,我尝试使用两个AD端口,389和3268.
我现在要查看其他Java LDAP库,但我想知道是否有其他人遇到过这些问题,或者有人知道为什么会这样,以及如何解决这个问题?即有没有办法从AD获得正确的值?
现在,我使用UnboundID LDAP SDK进行了相同的操作,这可以正常工作并返回完整和正确的objectSid以及objectGUID。因此,这似乎是标准J2SE库中的错误?
如果有人感兴趣的话,执行以下操作的代码:
private static void unboundIdLdapSearch(final String ldapADServer, final String bindDN, final String bindCredential, final String baseCtxDN, final String userName) throws LDAPException, Exception {
final LDAPConnection connection = new LDAPConnection(ldapADServer.substring(0, ldapADServer.indexOf(':')),
Integer.parseInt(ldapADServer.substring(ldapADServer.indexOf(':') + 1)), bindDN, bindCredential);
findAccountByAccountName(connection, baseCtxDN, userName);
connection.close();
}
private static void findAccountByAccountName(final LDAPConnection connection, final String baseCtxDN, final String accountName) throws Exception {
final String searchFilter = "(&(objectClass=user)(sAMAccountName=" + accountName + "))";
logger.info("LDAP search filter: {}", searchFilter);
final SearchRequest request = new SearchRequest(baseCtxDN, SearchScope.SUB, searchFilter);
final com.unboundid.ldap.sdk.SearchResult result = connection.search(request);
final int numOfResults = result.getEntryCount();
final StringBuilder builder = new StringBuilder();
builder.append("Search returned with ").append(numOfResults).append(" results: ").append(StringUtils.NEW_LINE);
for (final SearchResultEntry entry : result.getSearchEntries()) {
builder.append(LdapHelper.getSearchResultDetails(entry, ""));
}
logger.info("Search results: {}{}", StringUtils.NEW_LINE, builder.toString());
}
Run Code Online (Sandbox Code Playgroud)
另外,我偶然发现为什么JNDI LDAP方法不能对objectSid和objectGUID正常工作,并且使它在我的UnboundID解决方案之外也可以工作。
首先,我意识到,当我使用'getValue'的UnboundID方法返回一个字符串时,它还返回了与J2SE JNDI版本相同的值,当我发现这可以将String转换为UTF-8时,导入值。
然后,我碰巧遇到了另一篇博客文章(http://www.jroller.com/eyallupu/entry/java_jndi_how_to_convert)以及以下页面:http : //docs.oracle.com/javase/jndi/tutorial/ldap/ misc / attrs.html。因此,要正确获取objectSid和objectGUID,所需要做的就是通过在LDAP上下文的映射中添加以空格分隔的属性名称列表,将它们添加到二进制属性列表中:
env.put("java.naming.ldap.attributes.binary", "objectSid objectGUID");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6680 次 |
| 最近记录: |