认证鉴权框架SpringSecurity-6--6.x版本升级篇
1、Springboot和springSecurity版本关系
前面少介绍了一个概念,springSecurity是spring家族的一员,springboot同样也是spring家族的一员。我们在pom中引入使用springboot时,需要指定springboot的版本。在引入springSecurity时,则不需要指定版本,spring会默认添加最匹配的版本。
版本主要关系如下:
Springboot2.X版本–对应springSecurity5.X版本
Springboot3.X版本–对应springSecurity6.X版本
2、5.X版本和6.X版本的区别
Spring Security 6.x 引入了一些重要的变化和改进,与之前的版本(如 Spring Security 5)相比有一些区别。最主要的区别就是弃用了WebSecurityConfigurerAdapter 类,使用了更加组件式的配置。简单来说就是直接定义一个或多个 SecurityFilterChain通过 bean方式注入spring容器中就达到了配置安全规则的结果。
3、升级改造流程
(1)、引入springboot3.X版本依赖
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-security-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- Spring Boot Starter Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
(2)、老版5.x版本的配置升级
1、老版本5.x配置类示例
import com.demo.exception.CustomAuthenticationFailureHandler;
import com.demo.exception.Http401AuthenticationEntryPoint;
import com.demo.filter.JWTAuthenticationFilter;
import com.demo.filter.JWTLoginFilter;
import com.demo.service.CustomAuthenticationProvider;
import com.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* SpringSecurity的配置
* 通过SpringSecurity的配置,将JWTLoginFilter,JWTAuthenticationFilter组合在一起
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/**白名单*/
private static final String[] AUTH_WHITELIST = {
"/v2/api-docs",
"/swagger-resources/**",
"/test/**"
};
@Autowired
private UserService userService;
@Autowired
private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
// 设置 HTTP 验证规则
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(
new Http401AuthenticationEntryPoint())
.and()
.addFilterBefore(new JWTLoginFilter(authenticationManager(),customAuthenticationFailureHandler,userService), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(authenticationManager(),userService), UsernamePasswordAuthenticationFilter.class); httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// 使用自定义认证提供者
auth.authenticationProvider(new CustomAuthenticationProvider(userService));
}
@Override
public void configure(WebSecurity web) throws Exception {
// 白名单接口放行
web.ignoring().antMatchers(AUTH_WHITELIST);
}
}
2、新版本6.x配置类示例
注意看的地方
import com.demo.exception.CustomAuthenticationFailureHandler;
import com.demo.exception.Http401AuthenticationEntryPoint;
import com.demo.filter.JWTAuthenticationFilter;
import com.demo.filter.JWTLoginFilter;
import com.demo.service.CustomAuthenticationProvider;
import com.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* SpringSecurity的配置
* 通过SpringSecurity的配置,将JWTLoginFilter,JWTAuthenticationFilter组合在一起
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class WebSecurityConfig {
/**白名单
*/
private static final String[] AUTH_WHITELIST = {
"/v2/api-docs",
"/swagger-resources",
"/test/**"
};
@Autowired
private UserService userService;
@Autowired
private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
@Bean 构建过滤器链返回
protected SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(
new Http401AuthenticationEntryPoint())
.and()
.addFilterBefore(new JWTLoginFilter(authenticationManager(),customAuthenticationFailureHandler,userService), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(authenticationManager(),userService), UsernamePasswordAuthenticationFilter.class);
httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
httpSecurity.authenticationProvider(new CustomAuthenticationProvider(userService)) 使用自定义认证提供者,直接封装到httpSecurity中
return http.build(); 构建过滤链并返回
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
白名单接口放行
return (web) -> web.ignoring().antMatchers(AUTH_WHITELIST);
}
}
(3)、升级总结
1、6.X的配置类不在继承WebSecurityConfigurerAdapter抽象类
2、HttpSecurity配置后,需要调用.build方法生成过滤器链返回,注入到容器中。
3、自定义的UserDetailService不需要AuthenticationManagerBuilder指定,直接注入spring容器就行。
4、自定义AuthenticationProvider认证方式,通过HttpSecurity配置,添加到过滤器链中。
5、白名单返回WebSecurityCustomizer 对象。