For a Spring Boot application, I successfully configured a Spring LdapTemplate using annotations, including the LdapContextSource dependency with @Values 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.).