Spring Boot 3.1.9升级至3.2.3遇authenticationManager为null问题求助
问题:Spring Boot 3.2.3升级后禁用匿名认证引发
authenticationManager cannot be null错误 将Spring Boot项目从3.1.9升级到3.2.3后,运行测试时出现错误,定位到代码中httpsecurity.anonymous(AbstractHttpConfigurer::disable)这一行,报错信息为:
java.lang.IllegalArgumentException: authenticationManager cannot be null
当前SecurityFilterChain配置代码如下:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.securityContext(a->a.requireExplicitSave(false)) .authorizeHttpRequests(a->a.dispatcherTypeMatchers(DispatcherType.ERROR, DispatcherType.FORWARD).permitAll()); http.csrf(AbstractHttpConfigurer::disable).sessionManagement(a->a.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)); http.authorizeHttpRequests(a->a.requestMatchers(HttpMethod.GET, "/**").hasAnyAuthority(getAppPermissions()) .requestMatchers(HttpMethod.PUT, "/**").hasAnyAuthority(getAppPermissions()) .anyRequest().denyAll()) .anonymous(AbstractHttpConfigurer::disable) .exceptionHandling(b->b.accessDeniedPage("/unauthorized")); http.httpBasic(a->a.authenticationEntryPoint(authenticationEntryPoint)); http.headers(a->a.addHeaderWriter(new StaticHeadersWriter("Content-Security-Policy",getContentSecurityPolicy()))); return http.build(); }
注释掉.anonymous(AbstractHttpConfigurer::disable)后项目可正常构建,但这不是理想解决方案,想确认是否遗漏了必要配置。
解决方案
原因分析
Spring Boot 3.2.x对应Spring Security 6.2版本,该版本对禁用匿名认证的场景做了更严格的检查:当匿名认证被禁用后,所有请求都必须经过认证流程,此时框架要求必须存在一个有效的AuthenticationManager实例来处理认证请求,否则就会抛出该空指针异常。而3.1.9对应的旧版本中,默认逻辑允许在这种情况下使用隐式的默认管理器,因此不会触发该错误。
具体解决方法
方法1:显式配置AuthenticationManager Bean
添加一个基于Spring Security自动配置的AuthenticationManager Bean,它会自动复用你项目中已有的UserDetailsService或AuthenticationProvider配置:
@Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { return authConfig.getAuthenticationManager(); }
方法2:在HttpSecurity中指定自定义AuthenticationManager
如果你已有自定义的AuthenticationManager实例,可以直接在配置中关联:
// 假设你已经有一个名为customAuthenticationManager的Bean http.authenticationManager(customAuthenticationManager) .anonymous(AbstractHttpConfigurer::disable) // 其他原有配置...
方法3:补充用户认证基础配置
如果你的项目中还没有配置UserDetailsService或AuthenticationProvider,需要补充相关实现,比如基于内存的简单示例:
@Bean public UserDetailsService userDetailsService() { return new InMemoryUserDetailsManager( User.withUsername("your-user") .password("{noop}your-password") // {noop}表示不加密,生产环境请使用PasswordEncoder .authorities("ROLE_USER") .build() ); }
内容的提问来源于stack exchange,提问作者Sreenath Reddy
相关产品推荐
相关产品推荐

