【问题标题】:Spring-Security 5.7.2 - external LDAP Server - BadCredentialsException is thrownSpring-Security 5.7.2 - 外部 LDAP 服务器 - 抛出 BadCredentialsException
【发布时间】:2022-10-04 16:03:02
【问题描述】:

用例:

将 Spring-Boot 升级到版本2.7.2和 Spring 安全版本5.7.2.

在 SecurityConfiguration 配置类中配置的外部 LDAP 服务器 (通过LdapPasswordComparisonAuthenticationManagerFactory班级)。

问题:

在 Spring-Boot 应用程序启动期间抛出“BadCredentialsException:错误凭据”。

【问题讨论】:

  • 您能否重新处理这个问题,使问题部分作为一个主题问题单独存在,并将其答案作为答案单独发布?自我回答的问题在这里最受欢迎。
  • 您好@halfer,感谢您的推荐。
  • 欢迎来到堆栈溢出!请不要在您的问题标题或正文中添加“已解决”。请参阅what should I do when someone answers,了解如何表明您已经解决了问题。

标签: spring-boot spring-security ldap


【解决方案1】:

解决方案(为我工作):

pom.xml

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
  <version>2.7.2</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-data</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.ldap</groupId>
  <artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-ldap</artifactId>
</dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-ldap</artifactId>
</dependency>

安全配置.java

package com.example.app.config;

// imports

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration
{

    private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);

    private final TokenProvider tokenProvider;

    private final CorsFilter corsFilter;

    private final LdapConfiguration ldapConfiguration;

    private final SecurityProblemSupport securityProblemSupport;

    public SecurityConfiguration(
        TokenProvider tokenProvider,
        CorsFilter corsFilter,
        LdapConfiguration ldapConfiguration,
        SecurityProblemSupport securityProblemSupport
    ) {
        this.tokenProvider = tokenProvider;
        this.corsFilter = corsFilter;
        this.ldapConfiguration = ldapConfiguration;
        this.securityProblemSupport = securityProblemSupport;
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring()
            .antMatchers(HttpMethod.OPTIONS, "/**")
//            ...
            .antMatchers("/content/**");
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
            .exceptionHandling()
            .authenticationEntryPoint(securityProblemSupport)
            .and()
            .csrf()
            .disable()
            .headers()
            .frameOptions()
            .disable()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
//            .antMatchers(HttpMethod.GET,"...")
//            .permitAll()
//            ...
            .and()
            .apply(securityConfigurerAdapter());

        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource, LdapAuthoritiesPopulator authorities) throws AuthenticationException {
        LdapPasswordComparisonAuthenticationManagerFactory factory =
            new LdapPasswordComparisonAuthenticationManagerFactory(contextSource, new LdapShaPasswordEncoder());

        factory.setUserDnPatterns(ldapConfiguration.getUserDnPatterns());
        factory.setPasswordAttribute(ldapConfiguration.getPasswordAttribute());
        factory.setUserDetailsContextMapper(userDetailsContextMapper());
        factory.setLdapAuthoritiesPopulator(authorities);
        factory.setContextSource(contextSource);

        return factory.createAuthenticationManager();
    }

    @Bean
    LdapAuthoritiesPopulator ldapAuthoritiesPopulator() {
        String groupSearchBase = ldapConfiguration.getGroupSearchBase();

        DefaultLdapAuthoritiesPopulator authorities =
            new NestedLdapAuthoritiesPopulator(contextSource(), groupSearchBase);
        authorities.setGroupSearchFilter(ldapConfiguration.getGroupSearchFilter());

        return authorities;
    }

    @Bean
    @ConditionalOnMissingBean
    public ContextSource contextSource() {
        LdapContextSource source = new DefaultSpringSecurityContextSource(ldapConfiguration.getUrl());
        source.setUserDn(ldapConfiguration.getManagerDn());
        source.setPassword(ldapConfiguration.getManagerPw());

        return source;
    }


    @Bean
    public UserDetailsContextMapper userDetailsContextMapper() {
        return new LdapUserDetailsMapper()
        {
            @Override
            public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
//                ...
            }
        };
    }

    private JWTConfigurer securityConfigurerAdapter() {
        return new JWTConfigurer(tokenProvider);
    }

}

应用程序集成.yml

...
spring:
  ldap:
    urls: ldaps://external-ldapserver-uri.com:636
    base: ou=ExtranetUser,dc=domain,dc=com
    username: cn=admin,dc=domain,dc=com
    password: <password>

...

ldap:
  url: ldaps://external-ldapserver-uri.com:636
  urlPath: dc=domain,dc=com
  passwordAttribute: userPassword
  groupSearchFilter: member={0}
  groupSearchBase: ou=ExtranetUser
  userDnPatterns: cn={0},ou=ExtranetUser
  managerDn: cn=admin,dc=domain,dc=com
  managerPw: <password>

【讨论】:

    猜你喜欢
    • 2012-05-19
    • 2015-11-12
    • 2017-07-11
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 2022-11-19
    • 2020-07-18
    • 2016-08-29
    相关资源
    最近更新 更多