知識庫 / Spring RSS 訂閱

使用默認全局安全方案 in springdoc-openapi

Spring
HongKong
8
11:58 AM · Dec 06 ,2025

1. 概述

本教程將介紹如何配置默認全局安全方案,並將其作為API的默認安全要求,使用springdoc-openapi庫在Spring MVC Web應用程序中實現。此外,我們還將討論如何覆蓋這些默認的安全要求。

OpenAPI規範允許我們為API定義一組安全方案。我們可以全局配置API的安全要求,也可以按端點進行覆蓋和移除。

2. 環境搭建

作為我們使用 Spring Boot 構建 Maven 項目,讓我們來探索項目的環境搭建。 在本節結束時,我們將擁有一個簡單的 Web 應用。

2.1. 依賴項

該示例具有兩個依賴項。第一個依賴項是 spring-boot-starter-web。 這是構建 Web 應用的主要依賴項:

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

另一個依賴項是 springdoc-openapi-ui,它是一個庫,用於以 HTML、JSON 或 YAML 格式渲染 API 文檔:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.7.0</version>
</dependency>

2.2. 應用程序入口點

一旦依賴項準備就緒,我們來定義應用程序的入口點。

我們將使用 @SpringBootApplication 註解來啓動應用程序,並使用 SpringApplication 助手類來啓動它:

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

3. <em>springdoc-openapi</em> 基礎配置

一旦我們配置了 Spring MVC,我們來查看 API 語義信息。

我們將通過向 DefaultGlobalSecuritySchemeApplication 類添加 springdoc-openapi 註解,來定義默認的全局安全方案和 API 元數據。為了定義全局安全方案,我們將使用 @SecurityScheme 註解:

@SecurityScheme(type = SecuritySchemeType.APIKEY, name = "api_key", in = SecuritySchemeIn.HEADER)

我們選擇了 APIKEY 安全方案類型,但我們也可以配置其他安全方案,例如 JWT。 在定義安全方案後,我們將添加元數據併為 API 建立默認的安全要求。 我們使用 @OpenApiDefinition 註解來實現這一點:

@OpenAPIDefinition(info = @Info(title = "Apply Default Global SecurityScheme in springdoc-openapi", version = "1.0.0"), security = { @SecurityRequirement(name = "api_key") })

在此,`info 屬性定義了 API 元數據。 此外,`security 屬性確定了全局默認的安全要求。

讓我們看看帶有註釋後的 HTML 文檔會是什麼樣子。 我們將看到元數據和應用於整個 API 的安全按鈕:

4. 控制器

現在我們已經配置了 Spring 框架和 springdoc-openapi 庫,讓我們在應用程序的基礎路徑中添加一個 REST 控制器。 要實現這一點,我們將使用 @RestController@RequestMapping 註解:

@RestController
@RequestMapping("/")
public class DefaultGlobalSecuritySchemeOpenApiController {
    ...
}

之後,我們將定義兩個端點或 路徑

第一個端點是 /login 端點。它將接收用户憑據並對用户進行身份驗證。如果身份驗證成功,端點將返回一個令牌。

API 的另一個端點是 /ping 端點,它需要 /login 方法生成的令牌。在執行請求之前,該方法會驗證令牌並檢查用户是否已授權。

總而言之,/login 端點對用户進行身份驗證並提供令牌。/ping 端點接收由/login 端點返回的令牌,並檢查其有效性以及用户是否可以執行操作

4.1. login() 方法</h3

此方法將不具備任何安全要求。因此,我們需要覆蓋默認的安全配置要求

首先,我們需要告訴 Spring 這是一個 API 端點,因此我們將添加註解 @RequestMapping 以配置端點:

@RequestMapping(method = RequestMethod.POST, value = "/login", produces = { "application/json" }, consumes = { "application/json" })

之後,我們需要為端點添加語義信息。我們將使用 @Operation@SecurityRequirements 註解。 @Operation 將定義端點,而 @SecurityRequirements 將定義適用於該端點的特定安全要求:

@Operation(operationId = "login", responses = {
    @ApiResponse(responseCode = "200", description = "api_key to be used in the secured-ping endpoint", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = TokenDto.class)) }),
    @ApiResponse(responseCode = "401", description = "Unauthorized request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }) })
@SecurityRequirements()

以下是翻譯後的內容:

例如,以下是帶有狀態碼 200 的響應的 HTML 文檔:

最後,讓我們查看 login() 方法的簽名:

public ResponseEntity login(@Parameter(name = "LoginDto", description = "Login") @Valid @RequestBody(required = true) LoginDto loginDto) {
    ...
}

如我們所見,API 請求的主體接收一個 LoginDto 實例。 此外,我們還需要使用語義信息來裝飾 DTO,以便在文檔中顯示相關信息:

public class LoginDto {
    private String user;
    private String pass;

    ...

    @Schema(name = "user", required = true)
    public String getUser() {
        return user;
    }

    @Schema(name = "pass", required = true)
    public String getPass() {
        return pass;
    }
}

這裏我們可以看到 /login 端點的 HTML 文檔將是什麼樣子:

4.2. ping() 方法

在此階段,我們將定義 ping() 方法。 ping() 方法將使用默認全局安全方案。

@Operation(operationId = "ping", responses = {
    @ApiResponse(responseCode = "200", description = "Ping that needs an api_key attribute in the header", content = {
        @Content(mediaType = "application/json", schema = @Schema(implementation = PingResponseDto.class), examples = { @ExampleObject(value = "{ pong: '2022-06-17T18:30:33.465+02:00' }") }) }),
    @ApiResponse(responseCode = "401", description = "Unauthorized request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }),
    @ApiResponse(responseCode = "403", description = "Forbidden request", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ApplicationExceptionDto.class)) }) })
@RequestMapping(method = RequestMethod.GET, value = "/ping", produces = { "application/json" })
public ResponseEntity ping(@RequestHeader(name = "api_key", required = false) String api_key) {
    ...
}

主要的區別在於 login() 方法和 ping() 方法的應用需求。 login() 方法將不具備任何安全需求,而 ping() 方法將在 API 級別定義安全要求。因此,HTML 文檔將僅顯示對 /ping 終點的鎖圖標。

5. REST API 文檔 URL

此時,我們已經準備好 Spring MVC Web 應用,並且可以啓動服務器:

mvn spring-boot:run -Dstart-class="com.baeldung.defaultglobalsecurityscheme.DefaultGlobalSecuritySchemeApplication"

服務器準備就緒後,我們可以通過 http://localhost:8080/swagger-ui-custom.html 網址查看 HTML 文檔,如前例所示。

API 定義的 JSON 版本位於 http://localhost:8080/api-docs,YAML 版本位於 http://localhost:8080/api-docs.yaml

這些輸出可用於使用 swagger-codegen-maven-plugin 構建不同語言的 API 客户端或服務器。

6. 結論

在本文中,我們學習瞭如何使用 springdoc-openapi 庫定義默認全局安全方案。我們還了解了如何將其應用於 API 的默認安全要求。此外,我們還學習瞭如何為特定端點更改默認安全要求。

我們還發現,可以使用來自 springdoc-openapi 的 JSON 和 YAML 輸出自動生成代碼。

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

發佈 評論

Some HTML is okay.