将Spring Security XML配置迁移至Spring Boot Java配置咨询
Spring Security Java配置实现
以下是将你提供的Spring Security XML配置转换为Spring Boot Java配置的实现,完全对应原配置的功能:
基于WebSecurityConfigurerAdapter的实现(适配Spring Security 5.7以下版本)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity public class SecurityConfig { // 注册自定义LoginFilter,对应XML中的<beans:bean id="LoginFilter" class="com.codemaster.LoginFilter"/> @Bean public LoginFilter loginFilter() { return new LoginFilter(); } // 第一个HttpSecurity配置,对应XML中pattern="/dashboard*"的<http>块,优先级更高 @Configuration @Order(1) public static class DashboardSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http // 匹配/dashboard*路径 .antMatcher("/dashboard*") // 权限控制:/dashboard*需要ROLE_NORMAL_USER角色 .authorizeRequests() .antMatchers("/dashboard*").access("hasRole('ROLE_NORMAL_USER')") .and() // 表单登录配置 .formLogin() .loginPage("/logout") .defaultSuccessUrl("/dashboard") .failureUrl("/loginerrorpage") .and() // 会话并发控制:最多12个会话,过期跳转/logout .sessionManagement() .maximumSessions(12) .expiredUrl("/logout") .and() .and() // 添加自定义过滤器到LOGIN_PAGE_FILTER之后 .addFilterAfter(loginFilter(), UsernamePasswordAuthenticationFilter.class) // 登出配置 .logout() .invalidateHttpSession(true) .logoutUrl("/j_spring_security_logout") .logoutSuccessUrl("/logout") .and() // 禁用CSRF .csrf().disable(); } } // 第二个HttpSecurity配置,对应XML中第二个<http>块,优先级较低 @Configuration @Order(2) public static class DefaultSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http // 权限控制:/entrance需要ROLE_NORMAL_USER角色 .authorizeRequests() .antMatchers("/entrance").access("hasRole('ROLE_NORMAL_USER')") .and() // 表单登录配置 .formLogin() .loginPage("/login") .defaultSuccessUrl("/entrance") .failureUrl("/loginerrorpage") .and() // 会话并发控制 .sessionManagement() .maximumSessions(12) .expiredUrl("/logout") .and() .and() // 登出配置 .logout() .invalidateHttpSession(true) .logoutUrl("/j_spring_security_logout") .logoutSuccessUrl("/logout") .and() // 禁用CSRF .csrf().disable(); } } // 内存用户认证配置,对应XML中的<authentication-manager> @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user1") .password(passwordEncoder().encode("password1")) .roles("NORMAL_USER") .and() .withUser("user2") .password(passwordEncoder().encode("password2")) .roles("NORMAL_USER"); } // 密码编码器:适配原XML的明文密码(生产环境请替换为安全编码器) @Bean public PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } }
基于SecurityFilterChain的实现(Spring Security 5.7+官方推荐)
如果你的项目使用Spring Security 5.7.0及以上版本,建议使用组件式配置替代WebSecurityConfigurerAdapter:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public LoginFilter loginFilter() { return new LoginFilter(); } @Bean @Order(1) public SecurityFilterChain dashboardSecurityFilterChain(HttpSecurity http) throws Exception { http .antMatcher("/dashboard*") .authorizeRequests(auth -> auth .antMatchers("/dashboard*").access("hasRole('ROLE_NORMAL_USER')") ) .formLogin(form -> form .loginPage("/logout") .defaultSuccessUrl("/dashboard") .failureUrl("/loginerrorpage") ) .sessionManagement(session -> session .maximumSessions(12) .expiredUrl("/logout") ) .addFilterAfter(loginFilter(), UsernamePasswordAuthenticationFilter.class) .logout(logout -> logout .invalidateHttpSession(true) .logoutUrl("/j_spring_security_logout") .logoutSuccessUrl("/logout") ) .csrf(csrf -> csrf.disable()); return http.build(); } @Bean @Order(2) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeRequests(auth -> auth .antMatchers("/entrance").access("hasRole('ROLE_NORMAL_USER')") ) .formLogin(form -> form .loginPage("/login") .defaultSuccessUrl("/entrance") .failureUrl("/loginerrorpage") ) .sessionManagement(session -> session .maximumSessions(12) .expiredUrl("/logout") ) .logout(logout -> logout .invalidateHttpSession(true) .logoutUrl("/j_spring_security_logout") .logoutSuccessUrl("/logout") ) .csrf(csrf -> csrf.disable()); return http.build(); } @Bean public UserDetailsService userDetailsService() { UserDetails user1 = User.withUsername("user1") .password(passwordEncoder().encode("password1")) .roles("NORMAL_USER") .build(); UserDetails user2 = User.withUsername("user2") .password(passwordEncoder().encode("password2")) .roles("NORMAL_USER") .build(); return new InMemoryUserDetailsManager(user1, user2); } @Bean public PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } }
关键说明
- 多HttpSecurity配置:通过
@Order指定优先级,数字越小优先级越高,完全对应原XML的两个独立<http>块。 - 自定义过滤器:使用
addFilterAfter将LoginFilter添加到指定过滤器之后,对应XML的<custom-filter>配置。 - 密码编码器:
NoOpPasswordEncoder仅用于适配原XML的明文密码,生产环境必须替换为BCryptPasswordEncoder等安全编码器。 - 会话控制:
maximumSessions(12)和expiredUrl("/logout")完全对应原XML的会话并发配置。
内容的提问来源于stack exchange,提问作者Kunal Bhangale
相关产品推荐
相关产品推荐

