Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for configuring Spring LdapTemplate via annotations instead of XML?

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;     } } 
like image 212
Tim Avatar asked Aug 26 '14 21:08

Tim


People also ask

How does spring boot connect to LDAP server?

Spring Boot provides auto-configuration for an embedded server written in pure Java, which is being used for this guide. The ldapAuthentication() method configures things so that the user name at the login form is plugged into {0} such that it searches uid={0},ou=people,dc=springframework,dc=org in the LDAP server.

What is LdapTemplate?

public class LdapTemplate extends Object implements LdapOperations, InitializingBean. Executes core LDAP functionality and helps to avoid common errors, relieving the user of the burden of looking up contexts, looping through NamingEnumerations and closing contexts.

What is LDAP in Spring Security?

1. Overview. In this quick tutorial, we will learn how to set up Spring Security LDAP. Before we start, a note about what LDAP is – it stands for Lightweight Directory Access Protocol and it's an open, vendor-neutral protocol for accessing directory services over a network.


2 Answers

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.).

like image 112
M. Deinum Avatar answered Sep 27 '22 18:09

M. Deinum


Explicit wiring up of your LDAP isn't necessary at all for straight forward cases. This is the sort of thing Spring Boot aims to eliminate by being opinionated in the first place.

Ensure you have the spring-boot-starter-data-ldap or the spring-ldap-core dependency included, e.g. for Maven in your pom:xml:

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

Configure your LDAP in application.properties with the following keys:

# 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 

Then simply rely on Spring to autowire, e.g. using field injection1:

@Autowired private final LdapTemplate ldapTemplate; 

Reference: Spring Boot Reference Guide: LDAP


1 Field injection is generally not recommended but it's used here for concision.

like image 24
xlm Avatar answered Sep 27 '22 17:09

xlm