Spring Boot 2 和 Spring Boot 3 中使用 Spring Security 的区别
文章目录
- Spring Boot 2 和 Spring Boot 3 中使用 Spring Security 的区别
- 1. Jakarta EE 迁移
- 2. Spring Security 配置方式的变化
- 3. PasswordEncoder 加密方式的变化
- 4. permitAll() 和 authenticated() 的变化
- 5. 更强的默认安全设置
- 6. Java 17 支持与语法提升
- 7. @PreAuthorize、@Secured 注解的变化
- 8. 更强的 HTTP/2 和 TLS 支持
- 9. 更严格的 Bean 注入和依赖管理
Spring Boot 2 和 Spring Boot 3 中使用 Spring Security 的区别
从 Spring Boot 2 升级到 Spring Boot 3,特别是与 Spring Security 的集成和配置,存在一些显著的变化。这些变化主要是由于 Spring Security 5.x 和 6.x 之间的升级,以及 Java 17 的引入和一些基础框架的更新(例如 Jakarta EE 的迁移)。下面我详细说明这两者的主要差异。
1. Jakarta EE 迁移
Spring Boot 3 依赖 Jakarta EE 9,而 Spring Boot 2 使用的是 Java EE(javax 命名空间)。这一变化是 Spring Framework 6 的一部分,导致了 javax.* 命名空间的类迁移到 jakarta.*。
Spring Boot 2 使用的是 javax.servlet.、javax.validation. 等类。
Spring Boot 3 切换到 jakarta.servlet.、jakarta.validation.。
-
影响:
如果你的应用程序使用了 javax 命名空间中的类(例如过滤器、Servlets、JPA 等),在 Spring Boot 3 中需要手动迁移到 jakarta 命名空间。 -
解决方案:
在 Spring Boot 3 中,确保使用 jakarta.* 包替代 javax.*。
2. Spring Security 配置方式的变化
Spring Security 在 Spring Boot 3 中更推荐使用新的 DSL 配置,减少对 WebSecurityConfigurerAdapter 的依赖,这个类已经被弃用。
Spring Boot 2 配置方式(基于 WebSecurityConfigurerAdapter):
在 Spring Boot 2 中,通常通过继承 WebSecurityConfigurerAdapter 来配置安全设置。
@Configuration
public 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();
}
}
Spring Boot 3 配置方式(基于 SecurityFilterChain 和 Lambda DSL):
在 Spring Boot 3 中,WebSecurityConfigurerAdapter 已被弃用,取而代之的是基于 SecurityFilterChain 和 Lambda 风格的配置。
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login").permitAll()
)
.logout(logout -> logout.permitAll());
return http.build();
}
}
主要区别:
弃用了 WebSecurityConfigurerAdapter:Spring Boot 3 推荐使用更简洁的 SecurityFilterChain 和 Lambda 风格配置。
配置更加灵活:通过 Lambda 方式进行配置,增强了代码的可读性。
3. PasswordEncoder 加密方式的变化
Spring Boot 3 仍然使用 PasswordEncoder 来加密和验证密码,但与 Spring Boot 2 相比,密码加密的默认方式和推荐方式发生了细微变化。
Spring Boot 2:
在 Spring Boot 2 中,常见的加密方式是使用 BCryptPasswordEncoder,你可以手动选择或者直接用默认的 NoOpPasswordEncoder(明文)。
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
Spring Boot 3:
在 Spring Boot 3 中,仍然推荐使用 BCryptPasswordEncoder。不过,Spring Security 6.x 增加了对更强密码策略的关注,并逐渐抛弃了明文密码的方式。·
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder(); // 更灵活的密码加密器
}
注意:NoOpPasswordEncoder(不加密的明文存储)不再推荐使用,原因是安全性问题。
4. permitAll() 和 authenticated() 的变化
在 Spring Boot 3 中,HttpSecurity 的 API 有一些调整:
authorizeRequests() 被更改为 authorizeHttpRequests(),以更好地反映它的作用范围。
anyRequest().authenticated() 等表达方式依然存在,但推荐结合 Lambda 语法使用。
Spring Boot 2 示例:
http
.authorizeRequests()
.antMatchers("/public/**").permitAll() // 允许访问 /public/ 下的资源
.anyRequest().authenticated(); // 其他请求都需要认证
Spring Boot 3 示例:
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/public/**").permitAll() // 允许访问 /public/ 下的资源
.anyRequest().authenticated() // 其他请求需要认证
);
主要变化:从 authorizeRequests() 迁移到 authorizeHttpRequests(),使 API 更加符合 RESTful 风格和表达能力。
5. 更强的默认安全设置
Spring Boot 3 提供了更强的默认安全性配置,默认情况下对 CSRF、CORS、XSS 等安全性问题有更好的保护。
CSRF(跨站请求伪造)保护:默认开启,除非显式禁用。
HTTP Headers 安全性:Spring Security 6.x 默认增加了一些常见的安全头,比如 Strict-Transport-Security。
http
// 由于使用的是JWT,我们这里不需要csrf
.csrf(AbstractHttpConfigurer::disable)
// 基于token,所以不需要session
.sessionManagement(AbstractHttpConfigurer::disable);
在 Spring Boot 2 中,你可能需要手动配置某些安全头或 CSRF 保护。
http
.csrf().disable(); // 如果你不需要 CSRF,可以禁用
6. Java 17 支持与语法提升
Spring Boot 3 要求 Java 17 作为最低支持版本。对于使用 Java 17 的 Spring Boot 3 应用,你可以利用 Java 17 的新特性,例如 Records、sealed classes 等。
record UserDto(String username, String role) {}
@Bean
public UserDetailsService userDetailsService() {
return username -> {
if ("admin".equals(username)) {
return User.withUsername("admin")
.password("password")
.roles("ADMIN")
.build();
}
throw new UsernameNotFoundException("User not found");
};
}
7. @PreAuthorize、@Secured 注解的变化
@PreAuthorize 和 @Secured 注解在 Spring Boot 3 中仍然支持,不过在 Spring Security 6 中这些注解的使用方式保持不变,但是对于 @EnableGlobalMethodSecurity 的配置发生了变化。
Spring Boot 2:
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
Spring Boot 3:
@EnableMethodSecurity // 更简洁的配置方式
public class MethodSecurityConfig {
}
8. 更强的 HTTP/2 和 TLS 支持
Spring Boot 3 对 HTTP/2 和 TLS 的支持得到了加强,尤其是与安全性相关的配置更加灵活。Spring Security 6 默认包含对更强密码套件的支持,以及对新的 Web 技术(如 WebAuthn)的支持。
9. 更严格的 Bean 注入和依赖管理
Spring Boot 3 强调对依赖的更严格管理,尤其是在安全配置和其他关键组件的配置上,错误的配置将会更早暴露问题。这种变化使得应用程序在编译和启动时会更早发现配置错误,避免在运行时出现潜在的安全风险。