知識庫 / Spring / Spring Boot RSS 訂閱

Spring Boot 安全自動配置

Spring Boot,Spring Security
HongKong
5
02:05 PM · Dec 06 ,2025

1. 概述

本教程將探討 Spring Boot 對安全性的強定義向方法。

簡單來説,我們將重點關注默認的安全配置以及如果需要,如何禁用或自定義它。

2. 默認安全設置

為了增強我們的 Spring Boot 應用程序的安全性,我們需要添加 security starter 依賴項

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

這還將包含 SecurityAutoConfiguration 類,其中包含初始/默認的安全配置。

請注意,我們沒有在此處指定版本,假設該項目已經使用 Boot 作為父項目。

默認情況下,身份驗證已啓用 Application。 此外,內容協商用於確定是否應使用 basic 或 formLogin。

有以下預定義屬性:

spring.security.user.name
spring.security.user.password

如果未使用預定義的屬性 spring.security.user.password 配置密碼,並啓動應用程序,則默認密碼將在控制枱日誌中隨機生成並打印:

Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6

要了解更多默認值,請參閲 Spring Boot 常用應用程序屬性 參考文檔的 安全屬性 部分。

3. 取消自動配置

為了丟棄安全自動配置並添加我們的配置,我們需要排除 SecurityAutoConfiguration 類。

我們可以通過簡單的排除來實現:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class SpringBootSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSecurityApplication.class, args);
    }
}

或者,我們可以在 application.properties文件中添加一些配置:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration

然而,在某些特定情況下,這種配置可能不足以應付。

例如,幾乎每個 Spring Boot 應用都會以 Actuator 在 classpath 中啓動。 這會導致問題,因為另一個自動配置類需要我們剛剛排除的那個類。 這樣,應用程序將無法啓動。

為了解決這個問題,我們需要排除該類;並且,針對 Actuator 的情況,我們也需要排除 ManagementWebSecurityAutoConfiguration

3.1. 禁用與超越安全自動配置

禁用自動配置與超越自動配置之間存在顯著差異。

禁用它就像添加 Spring Security 依賴項並從頭開始進行整個設置。這在某些情況下很有用:

  1. 集成應用程序安全與自定義安全提供程序
  2. 將現有的 Spring 應用程序(已包含安全設置)遷移到 Spring Boot

但大多數情況下,我們不需要完全禁用安全自動配置。

這是因為 Spring Boot 配置為允許通過添加我們自己的自定義配置類來超越自動配置的安全設置。這通常更容易,因為我們只是在滿足我們的需求的情況下,自定義現有的安全設置。

4. 配置 Spring Boot 安全性

如果選擇禁用自動配置,我們自然需要提供自己的配置。

正如我們之前討論的,這是默認的安全配置。然後我們通過修改屬性文件對其進行自定義。

例如,我們可以通過添加自己的密碼來覆蓋默認密碼:

spring.security.user.password=password

如果我們需要更靈活的配置,例如使用多個用户和角色,則需要使用完整的 @Configuration 類:

@Configuration
@EnableWebSecurity
public class BasicConfiguration {

    @Bean
    public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
        UserDetails user = User.withUsername("user")
            .password(passwordEncoder.encode("password"))
            .roles("USER")
            .build();

        UserDetails admin = User.withUsername("admin")
            .password(passwordEncoder.encode("admin"))
            .roles("USER", "ADMIN")
            .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

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


    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        return encoder;
    }
}

@EnableWebSecurity 註解在禁用默認安全配置時至關重要。

如果應用程序缺少該註解,則無法啓動。

此外,請注意,在 Spring Boot 2 中使用時,您需要使用 PasswordEncoder 來設置密碼。有關更多詳細信息,請參閲 Spring Security 5 中默認密碼編碼器指南。

現在,我們應該通過進行一些快速的實時測試來驗證我們的安全配置是否正確應用:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class BasicConfigurationIntegrationTest {

    TestRestTemplate restTemplate;
    URL base;
    @LocalServerPort int port;

    @Before
    public void setUp() throws MalformedURLException {
        restTemplate = new TestRestTemplate("user", "password");
        base = new URL("http://localhost:" + port);
    }

    @Test
    public void whenLoggedUserRequestsHomePage_ThenSuccess()
     throws IllegalStateException, IOException {
        ResponseEntity<String> response =
          restTemplate.getForEntity(base.toString(), String.class);
 
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertTrue(response.getBody().contains("Baeldung"));
    }

    @Test
    public void whenUserWithWrongCredentials_thenUnauthorizedPage() 
      throws Exception {
 
        restTemplate = new TestRestTemplate("user", "wrongpassword");
        ResponseEntity<String> response =
          restTemplate.getForEntity(base.toString(), String.class);
 
        assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
        assertTrue(response.getBody().contains("Unauthorized"));
    }
}

Spring Security 實際上位於 Spring Boot Security 之下,因此可以使用此項或其支持的任何集成所能執行的任何安全配置也能夠應用於 Spring Boot。

5. 使用舊版棧的 Spring Boot OAuth2 自定義配置

Spring Boot 提供了專門的 OAuth2 自定義配置支持。

Spring Boot 1.x 中自帶的 Spring Security OAuth 支持在後續的 Boot 版本中被移除,取而代之的是與 Spring Security 5 捆綁的,原生 OAuth 支持。

對於舊版棧(使用 Spring Security OAuth),我們首先需要添加一個 Maven 依賴來開始配置我們的應用程序:

<dependency>
   <groupId>org.springframework.security.oauth</groupId>
   <artifactId>spring-security-oauth2</artifactId>
</dependency>

此依賴項包含一組能夠觸發 OAuth2AutoConfiguration 類中定義的自動配置機制的類。

現在,我們有多種選擇來根據應用程序的範圍繼續依賴。

5.1 OAuth2 授權服務器自動配置

如果我們的應用程序需要作為 OAuth2 提供方使用,我們可以使用 <em >@EnableAuthorizationServer</em>

在啓動時,我們會在日誌中注意到自動配置類會為我們的授權服務器生成一個 client ID 和 client secret,以及用於基本身份驗證的隨機密碼:

Using default security password: a81cb256-f243-40c0-a585-81ce1b952a98
security.oauth2.client.client-id = 39d2835b-1f87-4a77-9798-e2975f36972e
security.oauth2.client.client-secret = f1463f8b-0791-46fe-9269-521b86c55b71

這些憑據可用於獲取訪問令牌。

curl -X POST -u 39d2835b-1f87-4a77-9798-e2975f36972e:f1463f8b-0791-46fe-9269-521b86c55b71 \
 -d grant_type=client_credentials 
 -d username=user 
 -d password=a81cb256-f243-40c0-a585-81ce1b952a98 \
 -d scope=write  http://localhost:8080/oauth/token

另有一篇文章提供了更詳細的信息。

5.2. 其他 Spring Boot OAuth2 自動配置設置

以下是一些 Spring Boot OAuth2 覆蓋的用例:

  • 資源服務器 – <em @EnableResourceServer</em>>
  • 客户端應用程序 – <em @EnableOAuth2Sso</em>><em @EnableOAuth2Client</em>>

如果我們的應用程序需要成為這些類型之一,只需在應用程序屬性中添加一些配置,如鏈接中所述。

所有 OAuth2 相關的屬性可以在 Spring Boot 常用應用程序屬性 中找到。

6. 使用 New Stack 的 Spring Boot OAuth2 自動配置

為了使用 New Stack,我們需要根據我們想要配置的內容添加依賴項——一個授權服務器、一個資源服務器或一個客户端應用程序。

讓我們逐個分析它們。

6.1 OAuth2 授權服務器支持

正如我們所見,Spring Security OAuth 棧提供了將授權服務器配置為 Spring Application 的可能性。但是,該項目已被棄用,Spring 目前不提供自己的授權服務器。相反,建議使用成熟的提供商,例如 Okta、Keycloak 和 ForgeRock。

然而,Spring Boot 使得我們輕鬆配置這些提供商。例如,Keycloak 配置,可以參考《使用 Spring Boot 與 Keycloak 的快速指南》或《在 Spring Boot 應用程序中嵌入 Keycloak》。

6.2 OAuth2 資源服務器支持

為了支持資源服務器,我們需要添加以下依賴項:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>    
</dependency>

要獲取最新信息,請訪問 Maven Central

此外,在我們的安全配置中,我們需要包含 oauth2ResourceServer() DSL:

@Configuration
public class JWTSecurityConfig {
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
          ...
          .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
          ...
	}
}

我們的 OAuth 2.0 資源服務器與 Spring Security 5 深入探討了該主題。

6.3. OAuth2 客户端支持

類似於我們配置資源服務器的方式,客户端應用程序也需要其依賴項和 DSL。

以下是 OAuth2 客户端支持的具體依賴項:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

最新版本可以在 Maven Central 找到。

Spring Security 5 也通過其 oath2Login() DSL 提供一流的登錄支持。

有關新堆棧中 SSO 支持的詳細信息,請參閲我們的文章《使用 Spring Security OAuth2 實現簡單單點登錄》。

7. 結論

在本文中,我們重點介紹了 Spring Boot 提供的默認安全配置。我們瞭解了安全自動配置機制可以被禁用或覆蓋。此外,我們還探討了如何應用新的安全配置。

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

發佈 評論

Some HTML is okay.