知識庫 / Spring / Spring Security RSS 訂閱

從 Spring Security 5 遷移到 Spring Security 6/Spring Boot 3

Spring Security
HongKong
5
11:17 AM · Dec 06 ,2025

1. 概述

Spring Security 6 帶來了諸多重大變更,包括移除類、棄用方法以及引入新方法。

從 Spring Security 5 遷移到 Spring Security 6 可以分階段進行,而不會破壞現有的代碼庫。 此外,我們還可以使用第三方插件(如 OpenRewrite)來協助遷移到最新版本。

在本教程中,我們將學習如何使用 Spring Security 5 將現有應用程序遷移到 Spring Security 6。 我們將替換棄用方法並利用 lambda DSL 以簡化配置。 此外,我們還將利用 OpenRewrite 以加快遷移速度。

2. Spring Security 和 Spring Boot 版本

Spring Boot 基於 Spring 框架,Spring Boot 的版本使用 Spring 框架的最新版本。Spring Boot 2 默認使用 Spring Security 5,而 Spring Boot 3 使用 Spring Security 6。

要將 Spring Security 用於 Spring Boot 應用程序,我們始終將 spring-boot-starter-security 依賴項添加到 pom.xml 中。

但是,我們可以通過在 properties 部分的 pom.xml 中指定所需的版本來覆蓋默認的 Spring Security 版本:

<properties>
    <spring-security.version>5.8.9</spring-security.version>
</properties>

在此,我們指定項目中使用 Spring Security 5.8.9,覆蓋默認版本。

特別地,我們也可以在 Spring Boot 2 中使用 Spring Security 6,通過在 properties部分覆蓋默認版本來實現。

3. Spring Security 6 中的新功能

Spring Security 6 引入了多個功能更新,以提高安全性及健壯性。它現在需要 Java 17 或更高版本,並使用 jakarta 命名空間。

主要變更之一是棄用 WebSecurityConfigurerAdapter,轉而採用基於組件的安全性配置。

此外,authorizeRequests() 已被移除,並替換為 authorizeHttpRequests() 以定義授權規則。

更重要的是,它引入了 requestMatcher()securityMatcher() 方法來取代 antMatcher()mvcMatcher(),用於配置針對請求資源的安全性。 requestMatcher() 方法更安全,因為它選擇合適的 RequestMatcher 實現用於請求配置。

其他已棄用的方法,如 cors()csrf(),現在具有功能式替代方案。

4. 項目設置

為了開始,讓我們通過向 <em>pom.xml</em> 添加 <em><a href="https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web">spring-boot-starter-web</a></em>spring-boot-starter-security 來啓動一個 Spring Boot 2.7.5 項目:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.7.5</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.7.5</version>
</dependency>

spring-boot-starter-security 依賴於 Spring Security 5。

接下來,讓我們創建一個名為 WebSecurityConfig 的類:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}

在這裏,我們使用 @EnableWebSecurity 註解對類進行標註,以啓動對 Web 請求的安全性配置過程。同時,我們還啓用了方法級別的授權。接下來,該類繼承了 WebSecurityConfigurerAdapter 類,以提供各種安全配置方法。

此外,讓我們定義一個內存用户以用於身份驗證:

@Override
void configure(AuthenticationManagerBuilder auth) throws Exception {
    UserDetails user = User.withDefaultPasswordEncoder()
      .username("Admin")
      .password("password")
      .roles("ADMIN")
      .build();
    auth.inMemoryAuthentication().withUser(user);
}

在上述方法中,我們通過覆蓋默認配置創建了一個內存用户。

接下來,讓我們通過覆蓋 configure(WebSecurity web)方法來排除靜態資源,從而實現安全配置:

@Override
void configure(WebSecurity web) {
    web.ignoring().antMatchers("/js/**", "/css/**");
}

最後,讓我們通過覆蓋 configure(HttpSecurity http) 方法來創建 HttpSecurity

@Override
void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
      .antMatchers("/").permitAll()
      .anyRequest().authenticated()
      .and()
      .formLogin()
      .and()
      .httpBasic();
}

特別地,這個配置展示了典型的 Spring Security 5 配置。在下一部分,我們將把這段代碼遷移到 Spring Security 6。

5. 將項目遷移到 Spring Security 6

Spring 建議採用分階段遷移方法,以防止更新到 Spring Security 6 時破壞現有代碼。 在升級到 Spring Security 6 之前,我們首先可以將 Spring Boot 應用程序升級到 Spring Security 5.8.5,並更新代碼以使用新的功能

將應用程序升級到 5.8.5 有助於我們為版本 6 的預期更改做好準備。

在分階段遷移過程中,我們的 IDE 可以提醒我們已棄用的功能。 這有助於分階段更新過程。

為了簡化遷移過程,讓我們直接將示例項目遷移到 Spring Security 6,通過更新應用程序以使用 Spring Boot 版本 3.3.2。

如果應用程序使用 Spring Boot 版本 2,則可以在 properties部分指定 Spring Security 6。

為了開始遷移過程,讓我們修改 pom.xml以使用最新版本的 Spring Boot:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.3.2</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>3.3.2</version>
</dependency>

在初始設置中,我們使用 Spring Boot 2.7.5,它在底層使用 Spring Security 5。

值得注意的是,Spring Boot 3 的最小 Java 版本是 Java 17。

在後續的子章節中,我們將重構現有代碼以使用 Spring Security 6。

5.1. <em @Configuration 註解

在 Spring Security 6 之前,<em @Configuration 註解是 <em @EnableWebSecurity 的一部分,但隨着最新更新,我們必須使用 <em @Configuration 註解來標註我們的安全配置:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}

在這裏,我們引入了@Configuration註解到現有代碼庫中,因為它不再是@EnableWebSecurity註解的一部分。 此外,該註解也不再是@EnableMethodSecurity@EnableWebFluxSecurity@EnableGlobalMethodSecurity註解的一部分

此外,@EnableGlobalMethodSecurity已標記為棄用,並將被@EnableMethodSecurity取代。 默認情況下,它啓用 Spring 的 pre-post 註解,因此我們引入@EnableMethodSecurity以提供方法級別的授權。

5.2. `WebSecurityConfigurerAdapter

最新更新移除了 `WebSecurityConfigurerAdapter 類,並採用基於組件的配置方式:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
}

在這裏,我們移除了 <em>WebSecurityConfigurerAdapter</em>,從而消除了對安全配置的覆蓋方法。 相反,我們可以註冊一個 Bean 用於安全配置。 我們可以註冊 <em>WebSecurityCustomizer</em> Bean 來配置 Web 安全性,<em>SecurityFilterChain</em> Bean 來配置 HTTP 安全性,<em>InMemoryUserDetails</em> Bean 來註冊自定義用户等。

5.3. WebSecurityCustomizer Bean

通過發佈一個 WebSecurityCustomizer Bean,來修改排除靜態資源的那個方法:

@Bean
WebSecurityCustomizer webSecurityCustomizer() {
   return (web) -> web.ignoring().requestMatchers("/js/**", "/css/**");
}

WebSecurityCustomizer 界面取代了 configure(Websecurity web)WebSecurityConfigurerAdapter 接口中。

5.4. <em >AuthenticationManager</em > Bean

在之前的章節中,我們通過重寫 <em >configure(AuthenticationManagerBuilder auth)</em > 方法來自 `WebSecurityConfigurerAdapter> 創建了一個內存用户。

讓我們通過註冊 <em >InMemoryUserDetailsManager</em >> Bean 來重構身份驗證憑據邏輯:

@Bean
InMemoryUserDetailsManager userDetailsService() {
    UserDetails user = User.withDefaultPasswordEncoder()
      .username("Admin")
      .password("admin")
      .roles("USER")
      .build();

    return new InMemoryUserDetailsManager(user);
}

在這裏,我們定義了一個內存用户,併為其分配 USER 角色,以提供基於角色的授權。

5.5. HTTP 安全配置

在之前的 Spring Security 版本中,我們通過覆蓋 HttpSecurity 類中的 WebSecurityConfigurer 的 configure 方法來配置 HTTP 安全。由於該方法在最新版本中已被移除,因此我們現在應該註冊 SecurityFilterChain 豆以進行 HTTP 安全配置:

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
      .authorizeHttpRequests(
          request -> request
            .requestMatchers("/").permitAll()
            .anyRequest().authenticated()
      )
      .formLogin(Customizer.withDefaults())
      .httpBasic(Customizer.withDefaults());
   return http.build();
}

在上述代碼中,我們用 authorizeHttpRequests() 方法替換了 authorizeRequest() 方法。新的方法使用 AuthorizationManager API,從而簡化了重用和自定義。

此外,它通過延遲身份驗證查找來提高性能。身份驗證查找僅在請求需要授權時發生。

當沒有自定義規則時,我們使用 Customizer.withDefaults() 方法來使用默認配置。

此外,我們使用 requestMatchers() 而不是 antMatcher()mvcMatcher() 來安全資源。

5.6. RequestCache

The request cache helps save user requests when they are required to authenticate and redirect users to the request once they successfully authenticate. Before Spring Security 6, RequestCache checks on every incoming request to see if there are any saved requests to redirect to. This involved reading the HttpSession on every RequestCache.

However, in Spring Security 6, the request cache only checks if the request contains a special parameter name “continue“. This improves performance and prevents unnecessary reading of HttpSession.

6. 使用 OpenRewrite

此外,我們還可以使用第三方工具,如 OpenRewrite,將現有的 Spring Boot 應用遷移到 Spring Boot 3。由於 Spring Boot 3 使用 Spring Security 6,因此它也會將安全配置遷移到版本 6。

要使用 OpenRewrite,可以將 插件 添加到 pom.xml 中:

<plugin>
    <groupId>org.openrewrite.maven</groupId>
    <artifactId>rewrite-maven-plugin</artifactId>
    <version>5.23.1</version>
    <configuration>
        <activeRecipes>
            <recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0</recipe>
        </activeRecipes>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.openrewrite.recipe</groupId>
            <artifactId>rewrite-spring</artifactId>
            <version>5.5.0</version>
        </dependency>
    </dependencies>
</plugin>

在這裏,我們通過 recipe 屬性升級到 Spring Boot 版本 3。OpenRewrite 提供了大量的升級 Java 項目的菜譜。

最後,讓我們運行遷移命令:

$ mvn rewrite:run

上述命令將項目遷移到 Spring Boot 3,包括安全配置。然而,OpenRewrite 目前尚未使用 lambda DSL 對遷移後的安全配置進行操作。當然,這很可能在未來的版本中發生變化。

7. 結論

在本文中,我們學習了使用 Spring Security 5 遷移現有代碼庫到 Spring Security 6 的逐步指南,通過替換過時的類和方法來實現。此外,我們還了解了如何使用第三方插件來自動化遷移過程。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.