charmingcompanions.com

Securing a Simple Spring Boot REST API with LDAP Authentication

Written on

Chapter 1: Introduction to Spring Boot and LDAP

In this guide, we will explore how to set up a basic Spring Boot REST API, referred to as Simple API, and implement security using LDAP (OpenLDAP). The application will feature two endpoints: /public and /secured.

Essentially, LDAP (Lightweight Directory Access Protocol) acts as a centralized database for user information and serves as an authentication tool. Additionally, it can manage role assignments for application users. OpenLDAP is an open-source version of the LDAP protocol.

Let’s dive in!

Prerequisites

To follow along with this tutorial, ensure that Docker is installed on your machine.

Creating the Simple API Application

We will begin by creating a Spring Boot application using Spring Initializr. Name the application spring-boot-ldap-simple-api and include the dependencies for Spring Web and Spring Security. We will utilize Spring Boot version 3.1.3 and Java 17. Here’s the link to set up your environment.

Click the GENERATE button to download the zip file. After unzipping, open the spring-boot-ldap-simple-api project in your preferred IDE. Now, let's start developing the necessary classes.

Adding LDAP Dependencies

Next, we will modify the pom.xml file to include the following LDAP dependencies (code highlighted):

<dependency>

<groupId>org.springframework.ldap</groupId>

<artifactId>spring-ldap-core</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.security</groupId>

<artifactId>spring-security-ldap</artifactId>

</dependency>

Creating the SimpleApiController Class

We will now create the SimpleApiController class within the package com.example.springbootldapsimpleapi with the following code:

package com.example.springbootldapsimpleapi;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import java.security.Principal;

@RestController

public class SimpleApiController {

@GetMapping("/public")

public String getPublic() {

return "Hello World, this is a public endpoint";

}

@GetMapping("/secured")

public String getSecured(Principal principal) {

return "Hello %s, this is a secured endpoint".formatted(principal.getName());

}

}

The SimpleApiController class contains two methods for handling GET requests. The getPublic() method responds to requests at the /public URL, returning "Hello World, this is a public endpoint." This endpoint is accessible without authentication. On the other hand, the getSecured() method responds to requests at /secured, returning a personalized message for authenticated users.

Setting Up the WebSecurityConfig Class

Next, we will implement the WebSecurityConfig class in the com.example.springbootldapsimpleapi package with the following content:

package com.example.springbootldapsimpleapi;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.http.HttpMethod;

import org.springframework.security.config.Customizer;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;

import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

import org.springframework.security.config.http.SessionCreationPolicy;

import org.springframework.security.web.SecurityFilterChain;

@Configuration

@EnableWebSecurity

public class WebSecurityConfig {

@Bean

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

return http.authorizeHttpRequests(

authorizeHttpRequests -> authorizeHttpRequests

.requestMatchers(HttpMethod.GET, "/secured").authenticated()

.requestMatchers(HttpMethod.GET, "/public").permitAll()

.anyRequest().denyAll()

)

.httpBasic(Customizer.withDefaults())

.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))

.build();

}

}

The annotations @Configuration and @EnableWebSecurity indicate that this class is a configuration class for Spring Security. The securityFilterChain method sets up the security rules for HTTP requests, specifying that requests to /secured require authentication, while /public can be accessed freely.

Creating the LdapAuthenticationConfig Class

Next, we will define the LdapAuthenticationConfig class in the same package:

package com.example.springbootldapsimpleapi;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.ldap.core.support.BaseLdapPathContextSource;

import org.springframework.security.authentication.AuthenticationManager;

import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

import org.springframework.security.config.ldap.LdapBindAuthenticationManagerFactory;

import org.springframework.security.ldap.userdetails.PersonContextMapper;

@Configuration

@EnableWebSecurity

public class LdapAuthenticationConfig {

@Bean

public AuthenticationManager ldapAuthenticationManager(BaseLdapPathContextSource contextSource) {

LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);

factory.setUserDnPatterns(USER_DN_PATTERN);

factory.setUserDetailsContextMapper(new PersonContextMapper());

return factory.createAuthenticationManager();

}

private static final String USER_DN_PATTERN = "uid={0}";

}

This class configures bind authentication, where the LDAP server verifies user credentials provided during login. This method ensures sensitive information remains secure.

Updating the Application Properties

Finally, we will modify the application.properties file with the following configurations:

spring.application.name=simple-api

spring.ldap.urls=ldap://localhost:389

spring.ldap.base=ou=users,dc=mycompany,dc=com

spring.ldap.username=cn=admin,dc=mycompany,dc=com

spring.ldap.password=admin

spring.ldap.anonymousReadOnly=true

logging.level.org.springframework.security=DEBUG

Overview of Properties:

  • spring.application.name: Application name specification.
  • spring.ldap.urls: LDAP server address.
  • spring.ldap.base: Starting point in the LDAP directory for user information.
  • spring.ldap.username: Username for LDAP access.
  • spring.ldap.password: Password for LDAP access.
  • spring.ldap.anonymousReadOnly: Allows public read access to LDAP.
  • logging.level.org.springframework.security: Sets detailed logging for security events.

Implementing Tests

Starting OpenLDAP

To initiate the OpenLDAP Docker container, execute the following command in a terminal:

docker run --rm --name openldap

-p 389:389

-e LDAP_ORGANISATION="MyCompany Inc."

-e LDAP_DOMAIN=mycompany.com

osixia/openldap:1.5.0

Creating and Importing OpenLDAP Users

Create an LDIF file named ldap-mycompany-com.ldif in the root folder of the Simple API application containing user definitions.

To import this LDIF file into OpenLDAP, use the command:

ldapadd -x -D "cn=admin,dc=mycompany,dc=com" -w admin -H ldap://

-f ldap-mycompany-com.ldif

You can verify the imported user with:

ldapsearch -x -D "cn=admin,dc=mycompany,dc=com"

-w admin -H ldap://localhost:389

-b "ou=users,dc=mycompany,dc=com"

-s sub "(uid=*)"

Starting the Simple API

In a terminal, navigate to the root folder of the Simple API and run:

./mvnw clean spring-boot:run

Testing the Endpoints

Now that everything is set up, let’s test the endpoints. First, call the /public endpoint:

curl -i http://localhost:8080/public

Expected response:

HTTP/1.1 200

...

Hello World, this is a public endpoint

Next, attempt to access the /secured endpoint without credentials:

curl -i http://localhost:8080/secured

You should receive:

HTTP/1.1 401

...

Now, try accessing the /secured endpoint with valid credentials:

curl -i -u app-user:123 localhost:8080/secured

The expected response should be:

HTTP/1.1 200

...

Hello app-user, this is a secured endpoint

For invalid credentials, you can test with:

curl -i -u app-admin:123 localhost:8080/secured

curl -i -u app-user:124 localhost:8080/secured

In both cases, you should see:

HTTP/1.1 401

...

Shutting Down the Simple API and OpenLDAP

To stop the Simple API, press Ctrl+C in the terminal where it’s running. Similarly, do the same in the terminal running OpenLDAP.

Conclusion

In this guide, we have configured OpenLDAP as an identity provider for a Simple Spring Boot API, utilizing the Spring Security framework to secure endpoints. We also tested the application’s endpoints to confirm that the /secured endpoint is protected.

Support and Engagement

If you found this article helpful, please consider supporting it by:

  • Engaging with comments, claps, or questions.
  • Sharing on social media.
  • Following me on Medium, LinkedIn, and Twitter.
  • Subscribing to my newsletter for updates on new posts.

Chapter 2: Additional Resources

This video tutorial covers the basics of integrating Spring Boot, Spring Security, and LDAP from scratch.

This video goes in-depth on setting up Spring Boot LDAP Authentication with Spring Security and an LDAP server.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Transform Your Self-Talk: Embrace Positivity for a Better Life

Discover how changing your self-talk can enhance your life and break negative cycles.

Finding Clarity Through Mindful Walking: A 40-Day Journey

Discover the transformative power of mindful walking through a personal 40-day journey of recovery and self-awareness.

Snow Days and Online Learning: A Comedic Take on Change

Explore the humorous clash between traditional snow days and the rise of online learning in this satirical piece.

Unlocking Creativity: Overcoming the Myth of Writer's Block

Discover how to dispel the myth of writer's block and reignite your creativity through practical strategies and fresh perspectives.

The Future of Zero-Knowledge AI: Balancing Privacy and Progress

Exploring how zero-knowledge proofs could enable AI growth while safeguarding privacy.

# The Illusion of Productivity: Is Slack Just a Modern Email?

Exploring how Slack mimics email's distractions while compromising productivity and security.

Unveiling Gerry Turner: The Golden Bachelor’s Hidden Truths

Gerry Turner’s journey as The Golden Bachelor reveals a complex narrative of charm, grief, and potential hidden narcissism.

Embracing Life: Making Every Moment Matter

Reflect on the beauty of life and learn to make the most of every moment.