Securing Spring Boot applications with LDAP

LDAP is commonly used in Spring Boot applications as a source of authentication and authorization information. In this tutorial we will learn how to secure a simple Spring Boot Web application using an embedded LDAP Server.

Project set up

First of all, in order to build our project we need the following dependencies to run a Web application with LDAP:

<?xml version="1.0" encoding="UTF-8"?><project>
   <dependencies>
       	
      <dependency>
          		
         <groupId>org.springframework.boot</groupId>
          		
         <artifactId>spring-boot-starter-web</artifactId>
          	
      </dependency>
       	
      <dependency>
          		
         <groupId>org.springframework.boot</groupId>
          		
         <artifactId>spring-boot-starter-test</artifactId>
          		
         <scope>test</scope>
          	
      </dependency>
        	
      <dependency>
          		
         <groupId>org.springframework.boot</groupId>
          		
         <artifactId>spring-boot-starter-security</artifactId>
          	
      </dependency>
       	
      <dependency>
          		
         <groupId>org.springframework.ldap</groupId>
          		
         <artifactId>spring-ldap-core</artifactId>
          	
      </dependency>
       	
      <dependency>
          		
         <groupId>org.springframework.security</groupId>
          		
         <artifactId>spring-security-ldap</artifactId>
          	
      </dependency>
       	
      <dependency>
          		
         <groupId>org.springframework.security</groupId>
          		
         <artifactId>spring-security-test</artifactId>
          		
         <scope>test</scope>
          	
      </dependency>
       
   </dependencies>
    
</project>

Then the simple REST Controller we will secure is the following one:

@RestController
public class CustomerController {
  @Autowired CustomerRepository repository;

  @RequestMapping(
      method = RequestMethod.GET,
      produces = {"application/json"})
  public List<Customer> findAll() {
    return repository.getData();
  }

  @PostMapping(path = "/", consumes = "application/json", produces = "application/json")
  public ResponseEntity<Customer> addCustomer(@RequestBody Customer customer) throws Exception {
    repository.save(customer);
    return new ResponseEntity<Customer>(customer, HttpStatus.CREATED);
  }
}

For the sake of brevity, we don’t include the Spring Boot Main class and the CustomerRepository class. Chec out the full source code for this example at the end of the article.

In order to authorize our REST Controller with LDAP, we will need a @Configuration class which extends WebSecurityConfigurerAdapter:

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
  @Value("${ldap.urls}")
  private String ldapUrls;

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

  @Value("${ldap.username}")
  private String ldapSecurityPrincipal;

  @Value("${ldap.password}")
  private String ldapPrincipalPassword;

  @Value("${ldap.user.dn.pattern}")
  private String ldapUserDnPattern;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().fullyAuthenticated().and().formLogin();
  }

  @Override
  public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.ldapAuthentication()
        .groupSearchBase("ou=scientists")
        .contextSource()
        .url(ldapUrls + ldapBaseDn)
        .managerDn(ldapSecurityPrincipal)
        .managerPassword(ldapPrincipalPassword)
        .and()
        .userDnPatterns(ldapUserDnPattern);
  }
}

In the basic example above, any valid username and password belonging to “scientists” group will be authorized to access any HTTP Resource.

If you don’t have an out of the box LDAP configuration, you can just use the free online LDAP server which is available at ldap.forumsys.com.

The following application.properties is what you need to connect to the remote LDAP server:

ldap.enabled = true
ldap.urls= ldap://ldap.forumsys.com:389/ 
ldap.base.dn= dc=example,dc=com 
ldap.username= cn=read-only-admin,dc=example,dc=com 
ldap.password= password 
ldap.user.dn.pattern = uid={0}

You can now run the application with:

$ mvn clean install spring-boot:run

If you request the root HTTP GET (http://localhost:8080), a Login form will appear:

Spring boot LDAP tutorial

You can enter any of the available users, such as einstein/password. A simple JSON will be returned:

[{"id":1,"name":"frank"},{"id":2,"name":"john"}]

Using a Local LDAP Server

If you want to use a local LDAP server, all you have to do is changing the application.properties with the appropriate settings. For example we can test it against this example LDAP server:

https://github.com/fmarchioni/mastertheboss/tree/master/ldap/embedded

Here is the application.properties required to connect to the above Apache DS server:

ldap.urls=ldap://localhost:10389/ 
ldap.base.dn=dc=keycloak,dc=org 
ldap.username=uid=jbrown,ou=People,dc=keycloak,dc=org 
ldap.password=password 
ldap.user.dn.pattern =uid={0},ou=People

Source code for this article: https://github.com/fmarchioni/masterspringboot/tree/master/security/rest-ldap-security