在 springdoc-openapi 中應用默認全局安全方案
一、概述
在本教程中,我們將學習如何在 Spring MVC Web 應用程序中使用springdoc-openapi
庫配置默認全局安全方案並將其應用為 API 的默認安全要求。此外,我們將討論如何覆蓋這些默認的安全要求。
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>2.7.1</version>
</dependency>
另一個依賴項是**[springdoc-openapi-ui](https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui "springdoc-openapi-ui")**
,該庫將以 HTML、JSON 或 YAML 格式呈現 API 文檔:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.9</version>
</dependency>
2.2.應用程序入口點
一旦依賴關係準備好,讓我們定義應用程序的入口點。
我們將使用@SpringBootApplication
註釋來引導應用程序和**SpringApplication
幫助器類來啟動它**:
@SpringBootApplication
public class DefaultGlobalSecuritySchemeApplication {
public static void main(String[] args) {
SpringApplication.run(DefaultGlobalSecuritySchemeApplication.class, args);
}
}
3. springdoc-openapi
基礎配置
配置好 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()
方法
此方法沒有任何安全要求。因此,我們需要覆蓋默認的安全需求配置。
首先,我們需要告訴 Spring 這是我們 API 的一個端點,所以我們將添加註解@RequestMapping
來配置端點:
@RequestMapping(method = RequestMethod.POST, value = "/login", produces = { "application/json" }, consumes = { "application/json" })
之後,我們需要向端點添加語義信息。所以我們將使用@Operation
和@SecurityRequirements
註釋。 @Operation
將定義端點, @SecurityRequirements
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
URL 處看到 HTML 文檔,如前面的示例所示。
API 定義的 JSON 版本位於http://localhost:8080/api-docs
,YAML 版本位於http://localhost:8080/api-docs.yaml
。
這些輸出可用於使用[swagger-codegen-maven-plugin](https://mvnrepository.com/artifact/io.swagger.core.v3)
以不同語言構建 API 的客戶端或服務器。
六,結論
在本文中,我們學習瞭如何使用springdoc-openapi
庫來定義默認的全局安全方案。此外,我們還了解瞭如何將其作為 API 的默認安全要求。此外,我們還學習瞭如何更改特定端點的默認安全要求。
我們發現的另一件事是,我們可以使用springdoc-openapi
的 JSON 和 YAML 輸出自動生成代碼。
與往常一樣,本文的完整源代碼可在 GitHub 上獲得。