gpt4 book ai didi

java - LDAP 查询未从 Active Directory 返回正确的数据

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:36 24 4
gpt4 key购买 nike

我正在开发一种工具,用于从 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]

同一用户的 objectSid 通过 LDAP 结果:

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]

在 LDAP 结果中,似乎任何超过 128 的值都返回为 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]

这是我用来执行这些测试的代码的主要部分。

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());

LdapHelper 简单地遍历所有属性并以格式良好的字符串返回它们。 objectGUID 和 objectSid 以十六进制格式打印。

我使用 JRE 6 和 JRE 7 运行测试,结果相同。我们的 AD 服务器是 Window Server 2008 RC2,我尝试同时使用 AD 端口 389 和 3268。

我现在要研究其他 Java LDAP 库,但我想看看是否还有其他人遇到过这些问题,或者是否有人知道这是为什么以及如何解决它? IE。有没有办法从 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());
}

此外,我偶然发现了为什么 JNDI LDAP 方法不能为 objectSid 和 objectGUID 正常工作,并且在我的 UnboundID 解决方案之外让它工作。

首先,我意识到当我使用返回字符串的“getValue”的 UnboundID 方法时,它也返回了与 J2SE JNDI 版本相同的值,当时我发现这会将字符串转换为 UTF -8 的进口值(value)。

然后我碰巧看到了另一篇博文 ( 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");

关于java - LDAP 查询未从 Active Directory 返回正确的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13128180/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com