opencodez

Simple Way to Configure LDAP Authentication using Spring Boot – Source Code on GitHub

LDAP authentication is one of the widely used approaches in enterprise-grade applications.  LDAP is used as a central repository for user information and applications will connect to this repository for user searches and authentication.

Configure LDAP Authentication using Spring Boot:

In this article, we will see how to do LDAP authentication using Spring Boot. Along with Spring Boot, we are using an online free LDAP  test server setup for user information. We will use the information provided by them to configure a connection in our project.

Software used in this example

Demo Project Structure

As we are using a web application along with usual spring boot dependency we need to add dependencies for ldap and thymeleaf for template system. The entries in pom will be like

xdependencyx
	xgroupIdxorg.springframework.ldapx/groupIdx
	xartifactIdxspring-ldap-corex/artifactIdx
x/dependencyx
xdependencyx
	xgroupIdxorg.springframework.securityx/groupIdx
	xartifactIdxspring-security-ldapx/artifactIdx
x/dependencyx
xdependencyx
	xgroupIdxorg.springframework.bootx/groupIdx
	xartifactIdxspring-boot-starter-thymeleafx/artifactIdx
x/dependencyx

For LDAP connection we need set few parameters like server url, port, principal user, password, base domain name. This information you can get from your LDAP or Active Directory team. In our case we are using sample online server and they have made this information available for us. We will keep these as properties in our application properties file.

ldap.enabled = true

####### LDAP ##############
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}

If you connect to the sample server from any of your LDAP Browser, you will see the directory structure like below 

From above image you can check how we came down to base domain name, user pattern etc. Once we have these properties set we will add a security config bean to our project which will configure a Ldap connection using these properties.

package com.opencodez.adldapdemo.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig  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;
	
	@Value("${ldap.enabled}")
	private String ldapEnabled;
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
        http
        	.authorizeRequests()
        		.antMatchers("/login**").permitAll()
        		.antMatchers("/profile/**").fullyAuthenticated()
            	.antMatchers("/").permitAll()
            	.and()
            .formLogin()
            	.loginPage("/login")
            	.failureUrl("/login?error")
            	.permitAll()
            	.and()
            .logout()
            	.invalidateHttpSession(true)
            	.deleteCookies("JSESSIONID")
            	.permitAll();
	}
	
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		
		if(Boolean.parseBoolean(ldapEnabled)) {
			auth
				.ldapAuthentication()
				.contextSource()
					.url(ldapUrls + ldapBaseDn)
						.managerDn(ldapSecurityPrincipal)
						.managerPassword(ldapPrincipalPassword)
					.and()
						.userDnPatterns(ldapUserDnPattern);
		} else {
	        auth
	        .inMemoryAuthentication()
	            .withUser("user").password("password").roles("USER")
	            .and()
	            .withUser("admin").password("admin").roles("ADMIN");
		}
	}

}

From above you can see that we have configured all urls under /profiles as secured. So if you are not authenticated and try to access the url you will be presented with a login form.

Also you can see that we have configured ldap authentication using spring boot based on a condition. If our properties file have a property ldap.enabled set to true then only the ldap configuration is triggered or else it will fall back to basic in-memory authentication.

Regarding html pages, we have simply mapped /login, /profile urls to respective thymeleaf  templates

Thats it on configuration front. Now we will run our application and access http://localhost:8999/profile .  You will be redirected to login page as

Now try and put any of the users from below. All users have a password as password

If you enter correct user/password you will be taken to profile page else it will show you login error.

You can download the code from our Github.

Download Code