Spring Boot:LDAP 错误:错误代码 49 - 80090308:LdapErr:DSID-0C090439,注释:AcceptSecurityContext 错误,数据 52e

问题描述 投票:0回答:1

我有一个 Spring Boot Web 应用程序,它像魅力一样使用 dao 身份验证。但我也想实现活动目录身份验证。

为了测试目的,我修改了我的 SecurityConfig,如下所示:

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();
    } 

}

看起来,由于添加了 activeDirectoryLdapAuthenticationProvider 并将 AuthenticationManager 设置为使用 activeDirectoryLdapAuthenticationProvider 作为唯一提供程序,我的应用程序正在使用此提供程序。

当我尝试登录时,我的应用程序抛出以下错误:

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

因为我已经搜索了整个互联网(感觉就是这样),我知道 52e 的意思是:用户名找到,但密码无效/错误。

问题是,事实并非如此!我已经在多个 LDAP / Active Directory 客户端上测试了我的帐户,该帐户运行 100%!

希望有人可以引导我走向正确的方向......

非常感谢,编码愉快...

萨沙

java spring-boot active-directory spring-security-ldap
1个回答
0
投票

最近,我们的 Spring Boot 应用程序之一收到了相同的错误消息,该应用程序通过非常相似的设置连接到 AD。该错误仅发生在一位特殊用户身上,并且密码是正确的。

我们观察到该问题是由密码中的特殊字符(德语“umlaut”)引起的。更改密码并删除变音符号解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.