Spring 1 WebSecurityConfig迁移至Spring 3遇循环引用问题求助
Spring 1 升级到 Spring 3:WebSecurityConfig 迁移至 SecurityFilterChain 解决方案
问题背景
将Spring 1应用升级至Spring 3,尝试用SecurityFilterChain替换原configure方法时出现循环引用错误,应用已升级到Java 17,可正常通过Maven启动,以下是迁移后的完整配置代码及关键改动说明。
迁移后的完整配置代码
@Configuration @EnableWebSecurity public class WebSecurityConfig { @Value("${web.WebSecurityConfig.gen_hashpass:false}") private Boolean gen_hashpass; @Autowired private WebUserDetailsService userDetailsService; /** * 构建AuthenticationManager,配置认证提供者 */ @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { AuthenticationManagerBuilder authBuilder = authConfig.getAuthenticationManagerBuilder(); authBuilder.authenticationProvider(authenticationProvider()); authBuilder.authenticationProvider(vwCasAuthenticationProvider()); return authBuilder.build(); } /** * 实例化DaoAuthenticationProvider */ @Bean public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); PasswordEncoder passwordEncoder = WebUser.getPasswordEncoder(); authProvider.setUserDetailsService(userDetailsService); authProvider.setPasswordEncoder(passwordEncoder); // 根据配置生成测试用加密密码 String hashPass = passwordEncoder.encode("bar"); if (gen_hashpass) { System.out.println(hashPass); } return authProvider; } @Bean public WebCasAuthenticationProvider vwCasAuthenticationProvider() { return new WebCasAuthenticationProvider(); } /** * 定义URL安全规则、登录/登出流程,替代原configure(HttpSecurity)方法 */ @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf().disable() .headers(headers -> headers.frameOptions(frame -> frame.sameOrigin())) .authorizeHttpRequests(auth -> auth .requestMatchers( "/", "/css/**", "/js/**", "/images/**", "/favicon.ico", "/favicon-epi.ico", "/debug/**", "/app/**", "/register", "/confirm", "/confirm/*", "/password-reset", "/password-reset/*", "/reset-password", "/reset-password/*", "/model/**", "/modal/**", "/project/*", "/user/**", "/feedback", "/monitoring/**", "/terms-of-service", "/privacy-policy", "/api/logging/*", "/sso/**", "/announcement/*", "/library/*", "/docs/**", "/api/eol/*", "/eol/model/**", "/researcher/join-experiment" ).permitAll() .anyRequest().authenticated() ) .formLogin(form -> form .loginPage("/modal/login") .successHandler(new LoginSuccessHandler()) .permitAll() ) .logout(logout -> logout .logoutSuccessUrl("/") .permitAll() ); return http.build(); } }
关键改动说明
- 移除WebSecurityConfigurerAdapter继承:Spring Security 5.7+已弃用该适配器类,改用基于Bean的配置方式,避免旧API带来的循环依赖风险
- 移除@Component注解:@Configuration已足够标识该类为配置类,无需额外添加@Component
- 重构AuthenticationManager配置:通过AuthenticationConfiguration获取AuthenticationManagerBuilder,直接在其中添加认证提供者,避免原代码中@Autowired注入Bean引发的循环依赖
- 使用SecurityFilterChain替代configure(HttpSecurity):采用Lambda风格配置HttpSecurity,更符合Spring 3的配置规范,同时保留原有的所有安全规则、登录登出逻辑
- 简化Bean定义:vwCasAuthenticationProvider直接返回实例,精简代码逻辑
循环引用问题解决说明
原代码中同时通过@Autowired注入authenticationProvider和vwCasAuthenticationProvider,又在同一类中定义这两个Bean,再加上WebSecurityConfigurerAdapter的内部逻辑,容易触发Spring的循环依赖检测。迁移后直接在authenticationManager方法中调用Bean创建方法,跳过@Autowired注入环节,彻底解决循环依赖问题。
内容的提问来源于stack exchange,提问作者shumway21
相关产品推荐
相关产品推荐

