【问题标题】:spring data ldap: LdapRespository - how to find user by DN?spring data ldap:LdapRespository - 如何通过 DN 查找用户?
【发布时间】:2020-01-19 15:02:35
【问题描述】:

我可能不明白 spring data ldap LdapRepository 是如何工作的,但我很困惑,因为我不知道如何通过 DN 找到 LDAP 用户。 例如,我目录中的用户如下所示:

dn: uid=nicolas,ou=mycompany,dc=com
objectclass: inetOrgPerson
objectclass: organizationalPerson
objectclass: person
objectclass: top
cn: nicolas
sn: nicolas
uid: nicolas
userPassword: $2a$12$qIaTIG3UVm0hfKRWbwO5EueXG.omG7FL0XmuVxlQ8UuJrozX8Tlk2

在 Spring Boot REST 控制器中,我得到当前经过身份验证的用户,如下所示:

   Map principal = (Map)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
   String dn = principal.get("dn");

这里的“dn”字符串是“uid=nicolas,ou=people,dc=mycompany,dc=com”

用户类如下:

@Entry(base = "ou=people", objectClasses = {"top", "person", "organizationalPerson", "inetOrgPerson", "simpleSecurityObject"})
public class RdfLdapUser
{
  @Id
  private Name id;

  @Attribute(name = "uid")
  private String uid;

  @Attribute(name = "cn")
  private String cn;

  @Attribute(name = "sn")
  private String sn;

  @Attribute(name = "dn")
  private String dn;
}

还有存储库:

@Repository
public interface RdfLdapRepository extends LdapRepository<RdfLdapUser>
{
  public Optional<RdfLdapUser> findByUid (String uid);
  public Optional<RdfLdapUser> findByDn (String dn);
}

尝试通过其 DN“uid=nicolas,ou=people,dc=mycompany,dc=com”查找用户会引发以下异常:

java.lang.NullPointerException: null
at java.util.Hashtable.put(Hashtable.java:460)
at org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy.setupEnvironment(SimpleDirContextAuthenticationStrategy.java:42)
at org.springframework.ldap.core.support.AbstractContextSource.setupAuthenticatedEnvironment(AbstractContextSource.java:194)
at org.springframework.ldap.core.support.AbstractContextSource.getAuthenticatedEnv(AbstractContextSource.java:582)
at org.springframework.ldap.core.support.AbstractContextSource.doGetContext(AbstractContextSource.java:134)
at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:158)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:357)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:309)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:642)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:578)
at org.springframework.ldap.core.LdapTemplate.find(LdapTemplate.java:1840)
at org.springframework.ldap.core.LdapTemplate.find(LdapTemplate.java:1861)
at org.springframework.ldap.core.LdapTemplate.findOne(LdapTemplate.java:1869)

我在这里做错了什么?

另一件事是有一个注释@DnAttribute,我不明白它的含义。文档说:

表示字段将自动填充到条目的可分辨名称或从条目的可分辨名称填充。使用此注释注释的字段将自动填充找到条目的可分辨名称中的值。为了自动计算条目的 DN,必须在该类中的所有 DnAttribute 注释上指定 index() 值,并且这些属性值前面加上 Entry.base() 值将用于找出区别要创建和更新的条目的名称。

我只是不明白。我见过这样的例子:

@DnAttribute(value="uid", index=0)
private String uid;

但我不确定这应该是什么意思。据说DN是uid索引0。对我来说,DN是DN,uid是uid,我不明白DN是uid是什么意思。有人可以澄清一下吗?

非常感谢。

亲切的问候,

尼古拉斯

【问题讨论】:

  • LDIF 显示以下 dn: uid=nicolas,ou=mycompany,dc=com,那么您如何使用 base dn 'ou=people,ou=mycompany,dc=com' 执行搜索?此条目不是“用户条目”的父条目。它甚至可能不存在于您的 LDAP 目录服务器中。
  • 与我的问题无关,但为了满足您的好奇心,是的,在出于出版目的对其进行混淆之前,正确的 dn 包含 ou=people。关于我的问题有什么建议吗?

标签: spring-data spring-ldap


【解决方案1】:

一年后我在这里,希望我能提供帮助。我想在开头解释一下@DnAttribute 的工作原理。

当您尝试保存图片中的实体时,您需要像其他情况一样设置属性,尽管@DnAttribute 是@Transient,因此它们不会在 LDAP 中镜像,@DnAttribute 会导致组合 DN . Base DN 设置为 LdapContextSource。

例如当 Base DN = "DC=company,DC=com" 时,您将 DN 属性设置为实体:

  • firstLevelOu = "firstLevelOu",
  • company = "我们的公司",
  • secondLevelOu = "secondLevelOu",
  • name = "newGroup"

存储在 LDAP 中的记录的 DN 如下所示:“CN=newGroup,OU=secondLevelOu,OU=ourCompany,OU=firstLevelOu,DC=company,DC=com”

当你想从LDAP中获取这个组时,你只需要LdapRepository,方法findById()

你只需要传入方法relative DN,base DN是隐式设置的,所以relative DN是CN=newGroup,OU=secondLevelOu,OU=ourCompany,OU=firstLevelOu

编辑

LdapAdapterUtils.createLdapName:


import org.springframework.ldap.support.LdapUtils;

public final class LdapAdapterUtils {

    public static LdapName createLdapName(String relativeDN) throws BadRequestAppException {

        LdapName createdName;
        try {
            createdName = LdapUtils.newLdapName(relativeDN);
        } catch (InvalidNameException e) {
            throw new BadRequestAppException("Relative DN: " + relativeDN + "is not valid DN");
        }
        return createdName;
    }
}

【讨论】:

  • Peter,您能解释一下 LdapAdapterUtils 的来源吗?
  • @GaborGarami 我添加了方法声明。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 2018-07-13
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
  • 2020-12-09
相关资源
最近更新 更多