提问者:小点点

如何在Spring Data LDAP存储库中获取用户的完整DN


我正在创建一个用户管理应用程序的扩展,该应用程序使用SpringDataLdap存储库在OpenLDAP服务器中维护用户以进行身份验证(除了内部数据库),因为该应用程序已经在使用Spring5和SpringData存储库。

基本的用户和组存储库用于查找、创建和更新,只有一个例外:组成员资格,因为成员属性需要完整的DN(可分辨名称),不幸的是,用户存储库的@Id键是相对DN。

My Ldap base is              "dc=example,dc=com"
The UserRepository returns   "cn=user1,ou=users"
but I need the full DN:      "cn=user1,ou=users,dc=example,dc=com"

基本名称是从ApplicationConfig.java加载到ContextSource中的,但是由于存储库是动态生成的,而且我只定义了一个接口,所以我不知道如何注入它或属性并使用它编写代码。

我没有找到任何返回完整DN的方法。我通过这个问题和Spring LDAP的用户管理示例找到了一个看起来像是解决方案的方法。然而,这涉及到回到Spring LDAP LdapTemboard,这是从Spring Data LDAP存储库退回到更通用的查询模型的一步。此外,由于依赖关系冲突,我无法让示例自行构建或运行,所以我担心混合Spring Data LDAP和Spring Ldap模板的解决方案的寿命。

我正在寻找的是从用户、组或其存储库类中检索完整 DN 或基本名称的任何方法,以便我可以在将成员添加到组或查找成员的组时提供这些名称。


共1个答案

匿名用户

经过一些尝试和许多错误之后,我找到了一种相当干净的方法来获得Ldap基本路径,在服务类中注入ApplicationConfig中定义的ContextSource。对于其他想看这个的人来说:

应用程序配置.java

@Configuration
@PropertySource("classpath:ldap.properties")

...

@Value("${ldap.url}") String ldapUrl;
@Value("${ldap.base}") String ldapBase;
@Value("${ldap.user}") String ldapUser;
@Value("${ldap.password}") String ldapPassword;

@Bean
public LdapContextSource contextSource() {
    LdapContextSource contextSource = new LdapContextSource();
    contextSource.setUrl(ldapUrl);
    contextSource.setBase(ldapBase);
    contextSource.setUserDn(ldapUser);
    contextSource.setPassword(ldapPassword);
    return contextSource;
}

@Bean
LdapTemplate ldapTemplate(ContextSource contextSource) {
    return new LdapTemplate(contextSource);
}

MyServiceImpl.java

@Repository
@Transactional
public class MyServiceImpl implements MyService {

    @Autowired
    private LdapUserRepository userRepository;

    @Autowired
    private LdapGroupRepository groupRepository;

    @Autowired
    LdapContextSource contextSource;

    ...

    @Override
    public Collection<LdapGroup> findGroupByMember(Name name) {
        LdapName dName = LdapUtils.prepend(LdapUtils.removeFirst(name,
            contextSource.getBaseLdapName()), contextSource.getBaseLdapName());

        return groupRepository.findByMember(dName);
    }
}

借助LdapUtils方法删除和前置基本路径,我可以清理完整DN的任何传入名称。这使LdapGroupRepostory保持简单,只有一个接口类,其余由Spring Data LDAP完成:

LdapGroup存储库.java

public interface LdapGroupRepository extends LdapRepository<LdapGroup> {

    Optional<LdapGroup> findByName(String groupName);

    @Query("(member={0})")
    Collection<LdapGroup> findByMember(Name member);
}