Spring Boot: LDAP Error: error code 49 - 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e

2.8k views Asked by At

I have a Spring Boot Webapplication which is working with dao authentication like a charm. But i want to implement active directory authentication too.

For testing purposes I've modified my SecurityConfig like that:

package com.sheimann.demoapp.config;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.security.web.SecurityFilterChain;

import com.sheimann.demoapp.service.UserServiceImpl;


/**
 * The Class WebSecurityConfig.
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    /** The success handler. */
    @Autowired
    private CustomLoginSucessHandler sucessHandler;
    
    @Autowired
    private CustomLoginFailureHandler failureHandler;

    /**
     * User details service.
     *
     * @return the user details service
     */
    @Bean
    UserDetailsService userDetailsService() {
        return new UserServiceImpl();
    }

    /**
     * Password encoder.
     *
     * @return the b crypt password encoder
     */
    @Bean
    BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * Authentication provider.
     *
     * @return the dao authentication provider
     */
    @Bean
    DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService());
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
    
        ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider = 
        new ActiveDirectoryLdapAuthenticationProvider( "mydomainName.com", "ldap://mydcipaddress:389", "dc=my,dc=domain,dc=com");
    
        // to parse AD failed credentails error message due to account - expiry,lock, credentialis - expiry,lock
        activeDirectoryLdapAuthenticationProvider.setConvertSubErrorCodesToExceptions(true); 
        activeDirectoryLdapAuthenticationProvider.setUseAuthenticationRequestCredentials(true);
        activeDirectoryLdapAuthenticationProvider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");
        
        return activeDirectoryLdapAuthenticationProvider;
    }


    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return new ProviderManager(List.of(activeDirectoryLdapAuthenticationProvider()));
    }
 
    /**
     * Filter chain.
     *
     * @param http the http
     * @return the security filter chain
     * @throws Exception the exception
     */
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                // URL matching for accessibility
                .requestMatchers("/datatables/**",
                        "/css/**",
                        "/js/**",
                        "/webjars/**",
                        "/app.js",
                        "/app.css",
                        "/just-validate/**",
                        "/bootstrap-icons/**",
                        "/bootstrap/**",
                        "/popperjs/**",
                        "/select2-bootstrap-5-theme-1.3.0/**",
                        "/select2-4.1.0-rc.0/**",
                        "/jquery/**",
                        "/*.p12",
                        "/login",
                        "/register",
                        "/resetPw1",
                        "/resetPw2",
                        "/error",
                        "/logout",
                        "/images/**")
                .permitAll()
                .requestMatchers("/admin/**").hasAnyAuthority("ADMIN")
                .requestMatchers("/user/**").authenticated()
                .anyRequest().authenticated()
                .and()                
                // form login
                .csrf((csrf) -> csrf.disable())
                .formLogin(login -> login
                        .loginPage("/login")
                        .failureHandler(failureHandler)
                        .successHandler(sucessHandler)
                        .usernameParameter("email")
                        .passwordParameter("password"))
                // logout
                .logout(logout -> logout
                        .logoutSuccessUrl("/login?res=logoutSuccess"))
                .exceptionHandling(handling -> handling
                        .accessDeniedPage("/access-denied"))
                .authenticationManager(authenticationManager());
                
        // session
        /*
         * .and()
         * .sessionManagement()
         * .invalidSessionUrl("/login?res=sst");
         */
        //http.authenticationProvider(authenticationProvider());
        http.headers(headers -> headers.frameOptions().sameOrigin());
        return http.build();
    } 

}

As it seems, due to adding the activeDirectoryLdapAuthenticationProvider and set the AuthenticationManager to use the activeDirectoryLdapAuthenticationProvider as only provider, my application is using this provider.

Wehn i try to login, my application is throwing the following error:

Caused by: javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563]

as i've searched the whole internet already (it feels like that), i know that 52e means: Username found but password invalid / wrong.

The problem is, that is not the truth! I've tested my account on several ldap / active directory clients and the account is working 100%!

Hopefully someone is here that can put me in the right direction...

Many Thanks And happy coding...

Sascha

1

There are 1 answers

0
mrnst On

Recently, we had the same error message from one of our Spring Boot applications, which is connected to AD with a very similar setup. The error only occured for one special user, and the password was correct.

We observed that the problem was caused by a special character (German "umlaut") in the password. Changing the password and removing the umlaut fixed the problem.