【问题标题】:Spring Security java.lang.StackOverflowError exception after all providers所有提供者之后的 Spring Security java.lang.StackOverflowError 异常
【发布时间】:2015-08-26 06:45:48
【问题描述】:

环境:

  • 春季 4.1.6
  • Spring Security 4.0.1

我有 2 个身份验证提供程序 - 一个访问 ActiveDirectory,然后一个访问我创建的自定义数据库提供程序。以任何一个环境中的用户身份登录都可以完美运行。用户通过身份验证,应用程序继续运行。

但是,当输入无效用户并且两个提供商都无法进行身份验证时,我在页面上收到此异常:

java.lang.StackOverflowError
    org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:393)
    org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:394)
    org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:394)
    org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$UserDetailsServiceDelegator.loadUserByUsername(WebSecurityConfigurerAdapter.java:394)

这是我的 WebSecurityConfigurerAdapter 配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .formLogin().loginPage("/login").failureUrl("/login?error").defaultSuccessUrl("/overview").permitAll()
            .and()
                .logout().logoutSuccessUrl("/login?logout").permitAll()
            .and()
                .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .antMatchers("/favicon.ico").permitAll()
                .antMatchers("/**").hasRole("AUTH");
}

@Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
    authManagerBuilder
            .authenticationProvider(activeDirectoryLdapAuthenticationProvider())
            .userDetailsService(userDetailsService());

    authManagerBuilder
            .authenticationProvider(databaseAuthenticationProvider())
            .userDetailsService(userDetailsService());
}

@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
    ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(DOMAIN, URL);
    provider.setConvertSubErrorCodesToExceptions(true);
    provider.setUseAuthenticationRequestCredentials(true);
    provider.setUserDetailsContextMapper(userDetailsContextMapper());
    return provider;
}

@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
    UserDetailsContextMapper contextMapper = new MyUserDetailsContextMapper();
    return contextMapper;
}

@Bean
public MyDatabaseAuthenticationProvider databaseAuthenticationProvider() {
    return new MyDatabaseAuthenticationProvider();
}

除了一些用于映射和查找用户的自定义逻辑外,“MyDatabaseAuthenticationProvider”或“MyUserDetailsContextMapper”类并没有什么特别之处。

应用程序没有崩溃,但显然不是我想向用户显示的页面。 :)

关于如何摆脱 StackOverflowError 的任何想法?

【问题讨论】:

    标签: java spring spring-mvc spring-security


    【解决方案1】:

    我遇到了同样的问题,这就是我的解决方案:

    @Override
    protected void configure(AuthenticationManagerBuilder
    authManagerBuilder) throws Exception {
    ...
    .userDetailsService(userDetailsService());
    ...
    }
    

    userDetailsS​​ervice 之后的括号将它们删除并按预期工作的问题。 从你的代码 sn-p 我不能确定你从哪里得到 userDetailsS​​ervice,对我来说我有它@Autowired。

    【讨论】:

    • 正是!由于我只是使用默认的 Spring Security userDetailsS​​ervice,因此在提供程序中再次设置它实际上是多余的——完全没有必要!一旦我从两个提供商中删除该行,它就可以正常工作。谢谢!!!
    • @BrianWaldhart - 还有 zeisi。我很高兴这解决了您的问题,但是我遇到了同样的问题,并且无法从 zeisi 提供的解决方案中获得任何意义。 “userDetailsS​​ervice 之后的括号的问题 - 删除了它们并且它按预期工作。”什么括号?这是什么意思???
    • @SteveCohen - 如果你看我上面的例子,我删除的两行是“.userDetailsS​​ervice(userDetailsS​​ervice());”来自“config”方法的行。一旦我删除了这两行,一切正常。这是有道理的,因为基本上你是在用 getter 调用 setter(它变成了循环的!)。
    • 更清楚一点:删除 .userDetailsService(userDetailsService()) 行,因为它是默认行,并且您正在创建一个无限递归,将其传递给自身。
    【解决方案2】:

    我遇到了同样的问题,另一种解决方案适用于我的情况。不同的是,我只有用户名和密码,数据库身份验证。

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder
                .userDetailsService(userDetailsService())
                .passwordEncoder(passwordEncoder());
    }
    
    @Bean
    UserDetailsService userDetailsService() {
        return new UserDetailsService();
    }
    

    解决方法是将@Override 注释添加到@Bean 注释方法:

    @Bean
    @Override
    UserDetailsService userDetailsService() {
        return new UserDetailsService();
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-23
      • 2014-04-24
      • 1970-01-01
      • 1970-01-01
      • 2016-11-09
      • 1970-01-01
      • 2018-05-04
      • 2016-05-28
      相关资源
      最近更新 更多