通过注解配置Spring LdapTemplate的最佳实践,而不是使用XML?

36

我成功地使用注释配置了一个Spring LdapTemplate,包括从@Value的application.properties中注入LdapContextSource依赖。(太棒了!我找不到一个例子,所以这可能会帮助其他人。)

以下代码片段设置上下文源,将其注入到LdapTemplate中,并将其自动装配到我的DirectoryService中。

在Spring Boot应用程序中有更好/更清晰的设置ContextSource的方法吗?

application.properties(在类路径上):

ldap.url=ldap://server.domain.com:389
ldap.base:OU=Employees,OU=Users,DC=domain,DC=com
ldap.username:CN=myuserid,OU=employees,OU=Users,DC=domain,DC=com
ldap.password:secretthingy

MyLdapContextSource.java:

@Component
public class MyLdapContextSource extends LdapContextSource implements ContextSource {

    @Value("${ldap.url}")
    @Override
    public void setUrl(String url) { super.setUrl(url);  }

    @Value("${ldap.base}")
    @Override
    public void setBase(String base) {super.setBase(base); }

    @Value("${ldap.username}")
    @Override
    public void setUserDn(String userDn) {super.setUserDn(userDn); }

    @Value("${ldap.password}")
    @Override
    public void setPassword(String password) { super.setPassword(password); }
}

MyLdapTemplate.java:

@Component
public class MyLdapTemplate extends LdapTemplate {

    @Autowired
    public MyLdapTemplate(ContextSource contextSource) { super(contextSource); }
}

DirectoryService.java:

@Service
public class DirectoryService {

    private final LdapTemplate ldapTemplate;

    @Value("${ldap.base}")
    private String BASE_DN;

    @Autowired
    public DirectoryService(LdapTemplate ldapTemplate) { this.ldapTemplate = ldapTemplate; }

    public Person lookupPerson(String username) {
        return (Person) ldapTemplate.lookup("cn=" + username, new PersonAttributesMapper());
    }

    public List<Person> searchDirectory(String searchterm) {
        SearchControls searchControls = new SearchControls();
        searchControls.setCountLimit(25);
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

        List<Person> people = (List<Person>) ldapTemplate.search(
                BASE_DN, "cn=" + searchterm, searchControls, new PersonAttributesMapper());
        return people;
    }
}

为什么要这样子?为什么要这么多子类?为什么不直接在xml或Java配置中进行配置呢?仅仅为了配置而进行子类化似乎有些过度设计了... - M. Deinum
谢谢你的建议,M!(话虽如此,显然对于“为什么”的回答是因为我在学习并且它起作用了,但这也是为什么我把它放出来进行审查和提供更好/更干净的方法的建议。一个更友好的方式可能是,“为了更好/更干净的方法,创建一个配置类,使用@Configuration和返回所需bean类型的方法,使用Environment来获取Spring Boot属性而不是@Value。” - 我会尝试运行代码并报告结果。 - Tim
2个回答

61

为什么要使用那么多子类?只需使用配置来配置bean。可以使用XML或Java配置。

@Configuration
public class LdapConfiguration {

    @Autowired
    Environment env;

    @Bean
    public LdapContextSource contextSource () {
        LdapContextSource contextSource= new LdapContextSource();
        contextSource.setUrl(env.getRequiredProperty("ldap.url"));
        contextSource.setBase(env.getRequiredProperty("ldap.base"));
        contextSource.setUserDn(env.getRequiredProperty("ldap.user"));
        contextSource.setPassword(env.getRequiredProperty("ldap.password"));
        return contextSource;
    }

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

}

您的DirectoryService可以保持不变,因为它将自动连线到LdapTemplate

一个通用的经验法则是,您不希望扩展基础架构bean(例如DataSourceLdapTemplate),而是明确地配置它们。与此相反的是应用程序bean(服务,存储库等)。


再次感谢,M - 你的建议非常有效,减少了代码行数,并帮助我更好地理解基于注释的配置风格。 - Tim
自动配置仅适用于本地主机,但对于远程服务器,这是解决方案。 - Pirate

9

对于简单的情况,完全不需要显式连接LDAP。这就是Spring Boot一开始就采取强烈意见的原因所在。

确保已经包含了 spring-boot-starter-data-ldap 或者 spring-ldap-core 依赖关系,例如Maven中的 pom.xml 文件:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>

您可以通过以下键在application.properties中配置LDAP:

# Note the spring prefix for each and use just the CN for username
spring.ldap.url=ldap://server.domain.com:389
spring.ldap.base=OU=Employees,OU=Users,DC=domain,DC=com
spring.ldap.username=myuserid
spring.ldap.password=secretthingy

然后只需依赖Spring进行自动装配,例如使用字段注入1

@Autowired
private final LdapTemplate ldapTemplate;

参考资料:Spring Boot参考指南:LDAP


1 字段注入通常不建议使用,但这里为了简洁起见使用了。


1
这篇关于2014年的问题的更新非常棒。这些年来发生了很多变化。下次我使用LDAP时,会使用这些信息。谢谢! - Tim
今天这个对我解决与我们的LDAP服务器连接的问题非常有帮助。非常感谢你! - Ken Flake
有没有想法如何使用上述方法加载两个LDAP服务器配置? - s_u_f

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接