Configure User Authentication through Windows Active Directory Server in a Spring Boot Application

In this article we will try to authenticate a user to an external windows active directory domain server before granting him access to APIs.

Suppose you have a running windows AD server such
domain name — example.examplegroup.co.in
IP Address — 192.168.1.25

Steps:

  1. Add following dependencies to pom.xml file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>

2. Create a security configuration file

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
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;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
@Bean
public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {

ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider =
new ActiveDirectoryLdapAuthenticationProvider( "example.examplegroup.co.in", "ldap://192.168.1.25");

// to parse AD failed credentails error message due to account - expiry,lock, credentialis - expiry,lock
activeDirectoryLdapAuthenticationProvider.setConvertSubErrorCodesToExceptions(true);

return activeDirectoryLdapAuthenticationProvider;
}


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

3. Create Controller class that supports two APIs -

  • /hello — return “Hello World”
  • /user — return json object of authenticated user details received from windows AD server.
@RestController
public class MyController {

@GetMapping("/hello")
public String sayHello() {
return "hello world";
}
@GetMapping("/user")
public Authentication getLoggedUserDeatil() {

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
//get username
String username = auth.getName();
// concat list of authorities to single string seperated by comma
String authorityString = auth
.getAuthorities()
.stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(","));
// check if the user have authority -roleA
String role = "role_A";
boolean isCurrentUserInRole = auth
.getAuthorities()
.stream()
.anyMatch(role::equals);
//return Authentication object
return auth;
}}

Thats it.

If you try to access any of these api, you will be prompted with login form as shown below.

login form when trying to access API
API /hello output after authentication
API /user output after authentication

System Administrator and Full stack web developer.