Java RootDSE中的SearchRequest
我必须使用以下功能从广告服务器查询用户:Java RootDSE中的SearchRequest,java,active-directory,ldap,unboundid-ldap-sdk,Java,Active Directory,Ldap,Unboundid Ldap Sdk,我必须使用以下功能从广告服务器查询用户: public List<LDAPUserDTO> getUsersWithPaging(String filter) { List<LDAPUserDTO> userList = new ArrayList<>(); try(LDAPConnection connection = new LDAPConnection(config.getHost(),config.getPort(),config.g
public List<LDAPUserDTO> getUsersWithPaging(String filter)
{
List<LDAPUserDTO> userList = new ArrayList<>();
try(LDAPConnection connection = new LDAPConnection(config.getHost(),config.getPort(),config.getUsername(),config.getPassword()))
{
SearchRequest searchRequest = new SearchRequest("", SearchScope.SUB,filter, null);
ASN1OctetString resumeCookie = null;
while (true)
{
searchRequest.setControls(
new SimplePagedResultsControl(100, resumeCookie));
SearchResult searchResult = connection.search(searchRequest);
for (SearchResultEntry e : searchResult.getSearchEntries())
{
LDAPUserDTO tmp = new LDAPUserDTO();
tmp.distinguishedName = e.getAttributeValue("distinguishedName");
tmp.name = e.getAttributeValue("name");
userList.add(tmp);
}
LDAPTestUtils.assertHasControl(searchResult,
SimplePagedResultsControl.PAGED_RESULTS_OID);
SimplePagedResultsControl responseControl =
SimplePagedResultsControl.get(searchResult);
if (responseControl.moreResultsToReturn())
{
resumeCookie = responseControl.getCookie();
}
else
{
break;
}
}
return userList;
} catch (LDAPException e) {
logger.error(e.getExceptionMessage());
return null;
}
}
所有这些都会导致各种异常或空结果:
Caused by: LDAPSDKUsageException(message='A null object was provided where a non-null object is required (non-null index 0).
2020-04-01 10:42:22,902 ERROR [de.dbz.service.LDAPService] (default task-1272) LDAPException(resultCode=32 (no such object), numEntries=0, numReferences=0, diagnosticMessage='0000208D: NameErr: DSID-03100213, problem 2001 (NO_OBJECT), data 0, best match of:
''
', ldapSDKVersion=4.0.12, revision=aaefc59e0e6d110bf3a8e8a029adb776f6d2ce28')
无法从RootDSE查询用户 使用域,或者如果需要在林中跨域查询用户,请使用全局编录(在不同端口上运行,而不是LDAP的默认389/636) RootDSE仅包含元数据。可能应该在其他地方询问此问题以了解更多信息,但首先请阅读Microsoft的文档,例如:
所以,我真的花了很多时间在这方面。可以查询
RootDSE
,但这并不像人们想象的那么简单
我主要使用WireShark来查看他们的LDAP浏览器在做什么
结果发现我离得并不远:
如您所见,baseObject
在这里是空的。
另外,还有一个附加控件,它带有OID和ASN.1字符串308400000003020102
那么,这本可读性更强的《308400000003020102》到底做了什么
首先,我们把它解码成一些东西,我们可以阅读-在这种情况下,这将是int2
在二进制文件中,这将为我们提供:0 0 0 0 0 0 0 1 0
从文件中我们知道,我们有以下符号:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
|---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|-------|-------|
| x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | SSFPR | SSFDS |
或者我们只是从文档中获取int值:
=1
->SSFDS
SERVER\u SEARCH\u FLAG\u DOMAIN\u SCOPE
=2
->SSFPR
SERVER\u SEARCH\u FLAG\u PHANTOM\u ROOT
SSFPR
,其定义如下:
对于AD DS,指示服务器搜索除
从属于搜索库的应用程序NC副本,甚至
如果未在服务器上实例化搜索库。对于AD LDS
行为相同,只是它还包括应用程序NC
搜索中的副本。对于AD DS和AD LDS,这将导致
要在所有NC副本(应用程序NC除外)上执行的搜索
在从属于搜索库的DC上持有的AD DS DC上。
这将启用诸如空字符串之类的搜索基,这将导致
用于搜索所有NC副本(应用程序除外)的服务器
其持有的AD DS DC上的NCs
NC
代表命名上下文
,它们作为操作属性
存储在RootDSE
中,名称为namingContexts
另一个值,SSFDS
执行以下操作:
防止在搜索时生成连续引用
返回结果。这将执行与
LDAP\服务器\域\范围\ OID控件
因此,有人可能会问我为什么要这样做。事实证明,我有一个客户在一个DC下有几个子DC。如果我告诉搜索处理转介,执行时间相当长,因此这对我来说不是一个真正的选项。但当我关闭它时,我在定义BaseDN成为我想要检索其成员的组
通过Softerra的LDAP浏览器中的RootDSE
选项进行搜索要快得多,并且在不到一秒钟的时间内返回结果
我个人不知道为什么这要快得多-但是没有微软任何工具界面的ActiveDirectory
对我来说是一种黑魔法。但坦率地说,这不是我的专业领域
最后,我得到了以下Java代码:
SearchRequest searchRequest = new SearchRequest("", SearchScope.SUB, filter, null);
[...]
Control globalSearch = new Control("1.2.840.113556.1.4.1340", true, new ASN1OctetString(Hex.decode("308400000003020102")));
searchRequest.setControls(new SimplePagedResultsControl(100, resumeCookie, true),globalSearch);
[...]
使用的Hex.decode()
如下:org.bouncycastle.util.encoders.Hex
非常感谢Softerra的员工,他们或多或少地结束了我的广告之旅。结果是有点正确,但有一个简单的选择,让LDAP为您完成工作-请参见我的答案。感谢您的时间和贡献:)
SearchRequest searchRequest = new SearchRequest("", SearchScope.SUB, filter, null);
[...]
Control globalSearch = new Control("1.2.840.113556.1.4.1340", true, new ASN1OctetString(Hex.decode("308400000003020102")));
searchRequest.setControls(new SimplePagedResultsControl(100, resumeCookie, true),globalSearch);
[...]