文章目录
使用 `WebSecurityConfigurerAdapter`示例Spring Security 5.7 之后的推荐替代方法总结`WebSecurityConfig.java`解释总结
WebSecurityConfigurerAdapter
是 Spring Security 中的一个适配器类,专门用于帮助开发者配置 Web 应用的安全设置。它是一个方便的抽象类,允许我们通过继承它并重写其方法,来定制应用的安全行为,比如配置认证和授权规则、处理用户会话管理、跨站请求伪造 (CSRF) 防护等。
在 Spring Security 5.7 版本后,WebSecurityConfigurerAdapter
已被标记为过时,推荐使用新的配置方式。
使用 WebSecurityConfigurerAdapter
开发者可以通过继承 WebSecurityConfigurerAdapter
并重写其配置方法来自定义安全策略:
configure(HttpSecurity http)
方法:用于配置请求的授权规则和安全过滤器链。重写 configure(AuthenticationManagerBuilder auth)
方法:用于配置认证方式,比如基于内存的用户、数据库认证、LDAP 认证等。 示例
以下是一个 WebSecurityConfigurerAdapter
的简单示例:
import org.springframework.context.annotation.Configuration;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;@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/public/**").permitAll() // 允许公开访问的路径 .anyRequest().authenticated() // 其他请求需要认证 .and() .formLogin() // 启用表单登录 .loginPage("/login") // 自定义登录页面 .permitAll() .and() .logout() // 启用注销 .permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("{noop}password").roles("USER") .and() .withUser("admin").password("{noop}admin").roles("ADMIN"); }}
Spring Security 5.7 之后的推荐替代方法
在 Spring Security 5.7 及之后,WebSecurityConfigurerAdapter
被弃用,推荐使用 SecurityFilterChain
和 AuthenticationManager
的配置方式:
@Configurationpublic class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/public/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); return http.build(); } @Bean public InMemoryUserDetailsManager userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); UserDetails admin = User.withDefaultPasswordEncoder() .username("admin") .password("admin") .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(user, admin); }}
总结
WebSecurityConfigurerAdapter
是用于配置 Spring Security 的一个便利适配器类,虽然已在新版本中被替代,但它在旧版本中是主要的安全配置方式。通过新方法,开发者可以更灵活、模块化地管理 Web 应用的安全配置。
是的,你在 WebSecurityConfig
类中配置了 Spring Security,确保 MyAuthenticationProvider
和 PhoneAuthenticationProvider
被正确注册为认证提供者,并且自定义的认证过滤器也被添加到了过滤器链中。下面是对你的配置文件的详细解释:
WebSecurityConfig.java
package com.productQualification.api.config;import com.productQualification.api.filter.PhoneNumAuthenticationFilter;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.authentication.ProviderManager;import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;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.web.authentication.UsernamePasswordAuthenticationFilter;import org.springframework.web.cors.CorsConfiguration;import java.util.Arrays;/** * @author William Guo */@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyAuthenticationProvider myAuthenticationProvider; @Autowired private MyAuthenticationFailHandler myAuthenticationFailHandler; @Autowired private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler; @Autowired private PhoneAuthenticationProvider phoneAuthenticationProvider; @Value("${spring.profiles}") private String profiles; @Bean public PhoneNumAuthenticationFilter phoneNumAuthenticationFilter() throws Exception { PhoneNumAuthenticationFilter filter = new PhoneNumAuthenticationFilter(); filter.setAuthenticationManager(authenticationManagerBean()); // 设置认证管理器 filter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler); // 设置登录成功处理器 filter.setAuthenticationFailureHandler(myAuthenticationFailHandler); // 设置登录失败处理器 filter.setFilterProcessesUrl("/admin/signInByPhone"); // 设置处理的URL return filter; } @Bean public UsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter() throws Exception { UsernamePasswordAuthenticationFilter filter = new UsernamePasswordAuthenticationFilter(); filter.setAuthenticationManager(authenticationManagerBean()); // 设置认证管理器 filter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler); // 设置登录成功处理器 filter.setAuthenticationFailureHandler(myAuthenticationFailHandler); // 设置登录失败处理器 filter.setFilterProcessesUrl("/admin/signIn"); // 设置处理的URL return filter; } @Override protected void configure(HttpSecurity http) throws Exception { // 关闭csrf http.csrf().disable(); // 开启cors跨域支持 http.cors().configurationSource(request -> { CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues(); corsConfiguration.addAllowedMethod(CorsConfiguration.ALL); // 允许所有方法 corsConfiguration.setAllowCredentials(true); // 允许携带cookie if ("prod".equals(profiles)) { corsConfiguration.addAllowedOrigin("https://www.crossbiog.com"); corsConfiguration.addAllowedOrigin("http://www.crossbiog.com"); corsConfiguration.addAllowedOrigin("https://crossbiog.com"); corsConfiguration.addAllowedOrigin("http://crossbiog.com"); corsConfiguration.addAllowedOrigin("https://kxlist.cn"); corsConfiguration.addAllowedOrigin("https://www.kxlist.cn"); } return corsConfiguration; }); http.authorizeRequests() .anyRequest().permitAll() // 允许所有请求// .and().formLogin().loginPage("/admin/signIn").defaultSuccessUrl("/admin/signInSuccess")// .failureHandler(myAuthenticationFailHandler)// .antMatchers(HttpMethod.GET, "/admin/signIn")// .permitAll()// .antMatchers(HttpMethod.POST, "/admin")// .permitAll()// // swagger// .antMatchers(HttpMethod.GET, "/v2/api-docs", "/swagger-resources/**", "/webjars/**", "/swagger-ui.html")// .permitAll()// .anyRequest()// .authenticated()// .and()// .sessionManagement()// .and()// .httpBasic(); ; // 把账户密码验证过滤器加到拦截器链中 http.addFilterAt(myUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) .authenticationProvider(myAuthenticationProvider); // 注册账户密码验证提供者 // 把手机号认证过滤器加到拦截器链中 http.addFilterAfter(phoneNumAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) .authenticationProvider(phoneAuthenticationProvider); // 注册手机号验证提供者 } @Override protected AuthenticationManager authenticationManager() { ProviderManager authenticationManager = new ProviderManager(Arrays.asList(phoneAuthenticationProvider)); // 不擦除认证密码,擦除会导致TokenBasedRememberMeServices因为找不到Credentials再调用UserDetailsService而抛出UsernameNotFoundException authenticationManager.setEraseCredentialsAfterAuthentication(false); return authenticationManager; }}
解释
注解:
@Configuration
:标记该类为配置类。@EnableWebSecurity
:启用 Spring Security 的 Web 安全支持。@EnableGlobalMethodSecurity(prePostEnabled = true)
:启用全局方法安全,支持 @PreAuthorize
和 @PostAuthorize
注解。 注入依赖:
@Autowired
:注入 MyAuthenticationProvider
、MyAuthenticationFailHandler
、MyAuthenticationSuccessHandler
和 PhoneAuthenticationProvider
。 配置 CORS:
http.cors().configurationSource(...)
:配置 CORS 支持,允许特定的域名访问。 关闭 CSRF:
http.csrf().disable()
:关闭 CSRF 保护,适用于不需要 CSRF 保护的场景。 配置 HTTP 安全:
http.authorizeRequests().anyRequest().permitAll()
:允许所有请求,可以根据需要进行更细粒度的权限控制。http.addFilterAt(...)
:将 UsernamePasswordAuthenticationFilter
添加到过滤器链中,并注册 MyAuthenticationProvider
。http.addFilterAfter(...)
:将 PhoneNumAuthenticationFilter
添加到过滤器链中,并注册 PhoneAuthenticationProvider
。 配置认证管理器:
authenticationManager()
:重写 authenticationManager
方法,创建一个 ProviderManager
并注册 PhoneAuthenticationProvider
。设置 setEraseCredentialsAfterAuthentication(false)
以防止擦除认证密码。 总结
通过上述配置,Spring Security 会在用户尝试登录时调用 MyAuthenticationProvider
或 PhoneAuthenticationProvider
进行认证。确保你的 WebSecurityConfig
类正确配置了认证提供者和自定义的认证过滤器,这样在用户登录时,程序一定会经过这些类。
希望这些解释能帮助你更好地理解和配置 Spring Security。