LdapContext.search() 未返回自定义 Active Directory 属性

LdapContext.search() not returning custom Active Directory attributes

我想查询 Active Directory 用户属性,包括自定义属性。我收到的内置属性很好,但 Attributes 对象中的自定义属性为空。我知道它在那里并且已经设置好,因为我得到了在 PowerShell 程序中工作的等价物。

这是我正在做的事情:

SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrIDs = { "distinguishedName", "mail", "mycustomattribute"};
constraints.setReturningAttributes(attrIDs);

NamingEnumeration<SearchResult> answer = ldapContext.search("DC=mydomain,DC=lan", "sAMAccountName="
        + user, constraints);
if (answer.hasMore())
{
    Attributes attrs = answer.next().getAttributes();
    System.out.println("distinguishedName "+ attrs.get("distinguishedName"));
    System.out.println("mail "+ attrs.get("mail"));
    System.out.println("custom "+ attrs.get("mycustomattribute"));
}

这正确地输出了可分辨名称和邮件,但它为自定义属性输出了 null。

我首先使用 PowerShell 进行了测试,以确保属性设置正确。我做了一个$user = Get-ADUser ...,然后输出$user.mycustomattribute,得到了期望值。我的 Java 应用程序需要这个值。

这是我到目前为止的思考过程...

是否需要以不同方式访问自定义属性?我不确定,但是 Google 查询没有提出任何建议。

这可能与查询的域控制器没有该数据有关吗?在设置 LdapContext 对象时,我的环境属性确实有 hashtable.put(Context.REFERRAL, "follow");,所以我猜这就是规则。

我刚刚意识到,如果我使用 ADSI Edit(浏览数据的 MS 工具),自定义属性显示为 <not set> 如果我 运行 作为非域管理员用户,但如果我 运行 作为域管理员,它会在 ADSI Edit 中正确显示属性。我以为我已经弄明白了,所以我 运行 Java 应用程序作为域管理员,但它仍然不起作用(获取其他属性但不是自定义属性)。

终于想通了,感觉自己有点傻

当我 运行 ADSI Edit 并且它不会给我正确的值时,除非我是 运行 它作为域管理员,我认为这就是答案,确实如此,但我正试图通过 运行 我的程序 作为管理员来修复它。我仍然在我的上下文环境中向域控制器提供非管理员凭据。

hashtable.put(Context.SECURITY_PRINCIPAL, "non-admin account");

什么时候应该

hashtable.put(Context.SECURITY_PRINCIPAL, "admin account");

所以潜在的问题是我没有权限读取我正在搜索的自定义属性。我以为每个人都可以读取这些属性(事实上,设置它的 network/AD 管理员告诉我很多,否则我会更早检查),但事实并非如此。

寓意:不要总是相信提供给你的环境条件。我花了将近两天的时间,因为我没有质疑网络管理员提供的配置。 (虽然没有难过,但我也会犯错误。)