Setup Spring Security with Active Directory LDAP in Spring Boot Web Application

This post illustrates how to set up Spring Security in Spring Boot configuration with Active Directory LDAP for a Spring MVC web application. I will also show what needs to be configured for the embedded tomcat to accept HTTPS.

Spring Security with LDAP

To configure Spring Security in Spring Boot, add the following Configuration class to your project. Note the use of annotation @EnableWebMvcSecurity. The configuration class extends the WebSecurityConfigurerAdapter class in Spring Security. More information can be found in the Spring Security Reference here.

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

     @Value("${ldap.domain}")
     private String DOMAIN;

     @Value("${ldap.url}")
     private String URL;

     @Value("${http.port}")
     private int httpPort;

     @Value("${https.port}")
     private int httpsPort;

     @Override
     protected void configure(HttpSecurity http) throws Exception {
          /*
           * Set up your spring security config here. For example...
          */
          http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginUrl("/login").permitAll();
          /*
           * Use HTTPs for ALL requests
          */
          http.requiresChannel().anyRequest().requiresSecure();
          http.portMapper().http(httpPort).mapsTo(httpsPort);
     }

     @Override
     protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
          authManagerBuilder.authenticationProvider(activeDirectoryLdapAuthenticationProvider()).userDetailsService(userDetailsService());
     }

     @Bean
     public AuthenticationManager authenticationManager() {
          return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
     }
     @Bean
     public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
          ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(DOMAIN, URL);
          provider.setConvertSubErrorCodesToExceptions(true);
          provider.setUseAuthenticationRequestCredentials(true);
          return provider;
     }
}

Add HTTPS connector for embedded Tomcat in Spring Boot

Now that Spring Security is set up, you need to update the web server to accept requests from HTTPS. To do that using the embedded Tomcat server in Spring Boot, add the following EmbeddedServletContainerCustomizer bean to the application configuration as shown below. Note I am using anonymous inner classes here instead of lambda expression as I see in other examples for Java 7 compatibility. You will need a keystore file for this to work.

@Bean
EmbeddedServletContainerCustomizer containerCustomizer (

     @Value("${https.port}") final int port, 
     @Value("${keystore.file}") Resource keystoreFile,
     @Value("${keystore.alias}") final String alias, 
     @Value("${keystore.password}") final String keystorePass,
     @Value("${keystore.type}") final String keystoreType) throws Exception {
          final String absoluteKeystoreFile = keystoreFile.getFile().getAbsolutePath();
          return new EmbeddedServletContainerCustomizer() {
               public void customize(ConfigurableEmbeddedServletContainer container) {
                    TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) container;
                    tomcat.addConnectorCustomizers(new TomcatConnectorCustomizer() {
                         public void customize(Connector connector) {
                              connector.setPort(port);
                              connector.setSecure(true);
                              connector.setScheme("https");
                              Http11NioProtocol proto = (Http11NioProtocol) connector.getProtocolHandler();
                              proto.setSSLEnabled(true);
                              proto.setKeystoreFile(absoluteKeystoreFile);
                              proto.setKeyAlias(alias);
                              proto.setKeystorePass(keystorePass);
                              proto.setKeystoreType(keystoreType);
                        }
               });
           }
     };
 }

 

Getting Start with Spring Boot Configurations

Spring Boot allows development of Spring applications with minimum configuration. This is particular useful for developing microservices. This blog post will demonstrate a few things that may help in understanding how Spring Boot does its job of auto configuring a Spring application.

Auto-Configuration

So what has been configured?

The main feature of Spring Boot is its ability to automatically configuration the Spring application based on its included jar files. So the first thing you may want to look at is what have been configured for you. This can be done by running the application with the debug flag either by adding “–debug” to the command line or JVM argument “-Ddebug“. You will then see the “Auto Configuration Report” displayed in your console like below:

=========================
AUTO-CONFIGURATION REPORT
=========================

Positive matches:
—————–

AopAutoConfiguration
– @ConditionalOnClass classes found: org.springframework.context.annotation.EnableAspectJAutoProxy,org.aspectj.lang.annotation.Aspect,org.aspectj.lang.reflect.Advice (OnClassCondition)
– SpEL expression on org.springframework.boot.autoconfigure.aop.AopAutoConfiguration: ${spring.aop.auto:true} (OnExpressionCondition)

AopAutoConfiguration.JdkDynamicAutoProxyConfiguration
– SpEL expression on org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$JdkDynamicAutoProxyConfiguration: !${spring.aop.proxyTargetClass:false} (OnExpressionCondition)

// rest omitted…

Negative matches:
—————–

ActiveMQAutoConfiguration
– required @ConditionalOnClass classes not found: javax.jms.ConnectionFactory,org.apache.activemq.ActiveMQConnectionFactory (OnClassCondition)

// rest omitted…

The report should give you an indication of what have been configured for you. It depends mainly on what jar files you have included in your project dependencies.

Excluding an auto configuration

Spring Boot is designed so that you can gradually replaced the auto-configuration as needed. To exclude an auto configuration, use the exclude attribute of the @EnableAutoConfiguration annotation as below:

@Configuration
@ComponentScan
@EnableAutoConfiguration(exclude = ProcessEngineAutoConfiguration.class)
@ImportResource("classpath:/activiti.xml")
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

I am using the Activiti Spring Boot module here. Note instead of relying on its auto configuration setup, I have included the activiti.xml configuration file using the @ImportResource annotation to manually configure the process engine used by Activiti.

Configuration properties

Application properties, e.g. JDBC connection string, are to be set in the application.properties file in the classpath. Profile specific properties should be included in a separate application-<profile>.properties file located at the same directory of the application.properties file.

A list of commonly used property keys can be found in the Reference Guide (here). For example, to change the embedded web server port to 8181, add the following line the the application.properties file

### application.properties

server.port=8181

Logging

You may configure Spring Boot to use logging framework of your choice. But first, it may be useful to configure the logger properties and understand what has been configured for you. To do this, add the property of the format logging.level.<package name>=<level> to your application.properties file. For example, to display debug messages for Hibernate, add the following lilne:

logging.level.org.hibernate=DEBUG

That’s it. The above has helped me to get started with Spring Boot, to understand how auto configuration works. The Reference Guide provides a comprehensive documentation of the framework and various how-tos. There are also many tutorials and blog articles around for reference.