For a Spring Boot application, I successfully configured a Spring LdapTemplate
using annotations, including the LdapContextSource
dependency with @Value
s from application.properties. (Woot! I couldn’t find an example, so maybe this will help others.)
The snippets (below) setup the context source, inject it into an LdapTemplate
, and autowire that into my DirectoryService.
Is there a better/cleaner way to setup the ContextSource
in a Spring Boot app?
application.properties (on the classpath):
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; } }
Advertisement
Answer
Why all the subclasses? Just use configuration to configure the beans. Either XML or Java Config.
@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()); } }
Your DirectoryService
can remain the same as it will have the LdapTemplate
autowired.
A general rule of thumb is that you don’t want to extend your infrastructure beans (like DataSource
or LdapTemplate
) but configure them explicitly. This as opposed to your application beans (services, repositories etc.).