DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones Build AI Agents That Are Ready for Production
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
Build AI Agents That Are Ready for Production

Just dropped: New 2026 “Cloud-Native Foundations” Trend Report. See how teams are tackling complexity, cost & reliability.

AI can investigate. Engineers still decide. See how both work together across incident response in this DZone + Datadog webinar on Oct. 29.

Related

  • Authentication With Remote LDAP Server in Spring WebFlux
  • Authentication With Remote LDAP Server in Spring Web MVC
  • How to Implement Two-Factor Authentication in A Spring Boot OAuth Server? Part 2: Under the Hood
  • Implementing Authentication and Authorization With Vaadin

Trending

  • Handling Large API Responses Without Freezing the Client: A Practical Architecture With Temporal, Kafka, and RAG
  • RAG Is Not Enough: The Rise of Enterprise Knowledge Graphs for AI Systems
  • Building Resilient Event-Driven Applications Using Temporal
  • Prompt Caching: Overriding Tokenization for Faster and More Cost-Effective AI
  1. DZone
  2. Coding
  3. Frameworks
  4. Spring Security With LDAP Authentication

Spring Security With LDAP Authentication

In this article, an author shares their experience with Spring Security on a demo purpose application of which the source code is available on Github.

By 
Dilek Karadaş Mataracı user avatar
Dilek Karadaş Mataracı
·
Sep. 13, 21 · Tutorial
Likes (9)
Comment
Save
Tweet
Share
29.4K Views

Join the DZone community and get the full member experience.

Join For Free

In real-world applications on production systems; security is a top concern. This security concern is separated into two: Authentication and Authorization. Authentication mainly focuses on who can access to the application and authorization focuses on who can access which resources based on their authorities. 


Spring Security logo.


In this article I will share my experience with Spring Security on a demo purpose application of which source code is available on Github. In this project, I used LDAP Authentication method for authentication. For the token generation mechanism, I used a private/public RSA key method. Private key is used for token generation and public key is used for token validation.  

The aim of the project is to return a jwt token to the login user and the user will use this token to access resources in subsequent requests. The demo application offers two rest endpoints: one is for the authentication mechanism to take place (/auth-server) and the other is a representative rest resource (/resource). Anyone can access the "/auth-server" endpoint, but the access is restricted to the "/resource" endpoint. When the user logs into the system; there will be a rest call to the "/auth-server" endpoint for LDAP authentication. For successful authentication, there will be a jwt token in the response. The second rest call will be to the actual resource endpoint "/resource" with the token in the header as an Authentication object. We will see how this is done in the codebase.

It is very simple to enable Spring Security in your projects. You can do that by only adding a few dependencies. Let’s start to examine our demo application to see how things are done.

First; the two dependencies below will be added to the pom.xml to enable Spring Security. You can do this also when generating the project structure in spring initializer by adding Spring Security Component.

XML
 
	
        	org.springframework.boot
            spring-boot-starter-security
	

	
            org.springframework.security
            spring-security-test
            test
	


Apart from these, we need to add additional dependencies for LDAP. Spring gives us the opportunity to use an embedded LDAP server.


XML
 
	
		com.unboundid
		unboundid-ldapsdk
	
	
		org.springframework.ldap
		spring-ldap-core
	
	
		org.springframework.security
		spring-security-ldap
	


Security configuration is done based on a configuration file:

Java
 
@Configuration
@EnableWebSecurity
public class DemoSecurityConfiguration extends WebSecurityConfigurerAdapter
{
    private Environment env;
    public DemoSecurityConfiguration(Environment env){
        this.env = env;
    }
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.authenticationProvider(new LdapAuthenticationProvider(env)).eraseCredentials(false); 
    }
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception 
    {
        httpSecurity
                .authorizeRequests()
                .antMatchers("/auth-server").permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf()
                .disable()
                .httpBasic();
    }
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
   @Bean
    public JwtTokenProvider provider(){
        return new JwtTokenProvider();
    }
}


The @EnableWebSecurity annotation is used for enabling spring web security. Configuration class must extend from Spring’s WebSecurityConfigurerAdapter class. First, the configure method is needed for defining the authentication method. The second configure method is to define security properties. For authentication, I created a custom LdapAuthenticationProvider class. Inside the second configure method, we are authorizing any request to the endpoint “/auth-server,” but the other endpoints should be authenticated first. We disable CSRF and we use an HTTP basic authentication.

For an embedded LDAP server, in the application.properties file we should define some properties:

Properties files
 
spring.ldap.embedded.port=8389
spring.ldap.embedded.ldif=classpath:ldap.ldif 
spring.ldap.embedded.base-dn=dc=springframework,dc=org


We will read the LDAP structure from a LDIF file(ldap.ldif); LDAP server’s port will be 8389; the root directory will be dc=springframework,dc=org.

Below is the custom LDAP authentication provider class:

Java
 
@Component
public class LdapAuthenticationProvider implements AuthenticationProvider
{
    private Environment environment;
    public LdapAuthenticationProvider(Environment environment) {
        this.environment = environment;
    }
    private LdapContextSource contextSource;
    private LdapTemplate ldapTemplate;
    private void initContext()
    {  
        contextSource = new LdapContextSource();
        contextSource.setUrl(environment.getProperty("ldap.server.url"));
        contextSource.setAnonymousReadOnly(true);
        contextSource.setUserDn("uid={0},ou=people");
        contextSource.afterPropertiesSet();

        ldapTemplate = new LdapTemplate(contextSource);
    }
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException
    {
        initContext();
        Filter filter = new EqualsFilter("uid", authentication.getName());
        Boolean authenticate = ldapTemplate.authenticate(LdapUtils.emptyLdapName(), filter.encode(), authentication.getCredentials().toString());
        if (authenticate)
        {
            UserDetails userDetails = new User(authentication.getName(), authentication.getCredentials().toString()
                    , new ArrayList<>());
            Authentication auth = new UsernamePasswordAuthenticationToken(userDetails,
                    authentication.getCredentials().toString(), new ArrayList<>());
            return auth;
        }
        else
        {
            return null;
        }
    }

    @Override
    public boolean supports(Class authentication)
    {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}


The first LdapContext is prepared after an EqualsFilter operation is done based on the uid(username). If a match happens with the correct password, then an Authentication object is prepared and returned. Otherwise, it returns null.

After successful authentication, the JWTTokenProvider class prepares a token with below method: generateToken:

Java
 
public class JwtTokenProvider
{
    public static String generateToken(String userName) throws Exception
    {
        Instant now = Instant.now();
        String jwtToken = Jwts.builder()
                .claim("name", userName)
                .setSubject("jwt_token")
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(Date.from(now))
                .setExpiration(Date.from(now.plus(5l, ChronoUnit.MINUTES)))
                .signWith(SignatureAlgorithm.RS512, getPrivateKey())
                .compact();
        return jwtToken;
    }
    private static Key getPrivateKey() throws Exception
    {
        ClassLoader classLoader = JwtTokenProvider.class.getClassLoader();
        File file = new File(classLoader.getResource("private.key").getFile());
        byte[] rsaPrivateKeyArr = FileUtils.readFileToByteArray(file);
        String rsaPrivateKey = new String(rsaPrivateKeyArr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(rsaPrivateKey));
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(keySpec);
    }	
}


I used private/public RSA key method to generate the token. I generated a private key with the OpenSSL genrsa command and put this private key to a resource file as "private.key" in/resources folder. The jwt token is prepared based on this private key in generateToken method. Also, an expiration time can be set to the token with the setExpiration method.

In postman, we can call the rest endpoints as follows:Rest Endpoints screenshot 1.

Rest Endpoints screenshot 2.

Thanks for reading!

You can find the source code at Github.

Spring Security authentication Spring Framework

Opinions expressed by DZone contributors are their own.

Related

  • Authentication With Remote LDAP Server in Spring WebFlux
  • Authentication With Remote LDAP Server in Spring Web MVC
  • How to Implement Two-Factor Authentication in A Spring Boot OAuth Server? Part 2: Under the Hood
  • Implementing Authentication and Authorization With Vaadin

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook