【问题标题】:Why AuthenticationManager is throwing StackOverflowError?为什么 AuthenticationManager 会抛出 StackOverflowError?
【发布时间】:2020-02-24 03:54:53
【问题描述】:

我在拨打authenticationManger.authenticate()时收到StackOverflowError

java.lang.StackOverflowError: null at org.apache.commons.logging.LogAdapter$Slf4jLog.isDebugEnabled(LogAdapter.java:300) ~[spring-jcl-5.1.10.RELEASE.jar:5.1.10.RELEASE] 在 org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:162) ~[spring-security-core-5.1.6.RELEASE.jar:5.1.6.RELEASE] 在 org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:503) ~[spring-security-config-5.1.6.RELEASE.jar:5.1.6.RELEASE]

我正在尝试在我的应用程序中实现 JWT。我创建了JWTTOkenUtil、过滤器、控制器。但只有身份验证管理器不起作用。我也试过CustomAuthenticationManger,但同样的错误。

文件AppConfig.java

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class AppConfig  extends WebSecurityConfigurerAdapter{

    @Autowired
    private JwtUserDetailService jwtUserDetailService;

    @Autowired
    private JwtAuthenticationProvider jwtAuthenticationProvider;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(jwtAuthenticationProvider);

     //auth.userDetailsService(jwtUserDetailService).passwordEncoder(passwordEncoder());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests().antMatchers("/version").permitAll()
            .anyRequest().authenticated()
            .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(jwtRequestFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public JwtRequestFilter jwtRequestFilter() {
            return new JwtRequestFilter();
    }
}

【问题讨论】:

  • WebSecurityConfigurerAdapter.java:503 line number delegate.authenticate(authentication); 其中委托被声明为private AuthenticationManager delegate; 而且您还没有给出完整的日志,即使是格式不好的日志。但是在日志中我没有看到空指针,但它显示了java.lang.StackOverflowError: null at 这我可以弄清楚。由于您没有提供JwtAuthenticationProvider 的代码,问题似乎信息不完整。
  • 你不能重写 AuthenticationManager authenticationManager() 方法。 authenticationManager()WebSecurityConfigurerAdapterauthenticationManagerBean() 是两种不同的方法,您正在调用 super 类的 authenticationManagerBean() 方法,据我所知,这取决于 authenticationManager() 方法。这反过来会创建方法的循环调用。
  • @Hasan 正是堆栈溢出错误的来源。 authenticationManager 方法应该通过覆盖 authenticate 方法返回 AuthenticationManager 的实现。
  • @HasanCanSaral 您应该发布作为确认的答案。通常,那些浏览所选/赞成答案的人未阅读 cmets。你的解释帮助我解决了同样的问题。谢谢
  • @Floresj4 你说得对,我只是不知道它是否对 OP 有帮助。不过以防万一。

标签: spring spring-boot spring-security jwt


【解决方案1】:

authenticationManager()authenticationManagerBean()WebSecurityConfigurerAdapter 是两个不同的方法,并且您正在调用超类的 authenticationManagerBean() 方法,据我所知,该方法取决于 authenticationManager() 方法。这反过来会创建一个循环调用方法,最终导致StackOverflowError 异常。

您可以尝试不覆盖 AuthenticationManager authenticationManager() 方法,或者在这样做时返回可靠的实现。

【讨论】:

    【解决方案2】:

    你覆盖了错误的方法 authenticationManager(),它应该是 authenticationManagerBean()。

    【讨论】:

      【解决方案3】:

      您需要重写 WebSecurityConfigurerAdapter 类的 authenticationManagerBean() 方法,而不是重写 authenticationManager() 方法。

      这对我来说是一个有效的配置。

      @RequiredArgsConstructor
      @EnableWebSecurity
      public class SecurityConfigurer extends WebSecurityConfigurerAdapter {
      
          private final CustomUserDetailsService customUserDetailsService;
      
          @Override
          protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              auth.userDetailsService(customUserDetailsService);
          }
      
          @Override
          protected void configure (HttpSecurity http) throws Exception{
              http
                      .csrf()
                      .disable()
                      .authorizeRequests()
                      .antMatchers("/authenticate").permitAll()
                      .anyRequest().authenticated();
          }
      
          @Override
          @Bean
          public AuthenticationManager authenticationManagerBean() throws Exception{
              return super.authenticationManagerBean();
          }
      
      
          @Bean
          public PasswordEncoder passwordEncoder(){
              return NoOpPasswordEncoder.getInstance();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-16
        • 2014-09-17
        • 2023-01-22
        • 1970-01-01
        相关资源
        最近更新 更多