1. 概述
Springdoc-OpenAPI 是一個庫,它通過基於 OpenAPI 3 規範,自動化生成 Spring Boot 應用程序的服務文檔。
通過用户界面與我們的 API 交互,而無需實施一個,這非常方便。因此,讓我們看看如何消費端點,如果涉及授權。
在本教程中,我們將學習 如何使用 Springdoc 中的 Form Login 和 Basic Authentication(通過 Spring Security)來管理安全端點訪問。
2. 項目設置
我們將設置一個使用 Spring Security 保護的 Spring Boot Web 應用程序,並使用 Springdoc 生成文檔。
2.1. 依賴項
讓我們聲明項目所需的 Maven 依賴項。我們將添加 springdoc-openapi-starter-webmvc-ui,該依賴項負責與 Swagger-UI 集成,並提供默認可訪問的視覺工具,位於:
http://localhost:8080/swagger-ui.html<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>2.2. 示例 API
為了本文檔,我們將使用 Springdoc 生成文檔時作為源的示例 REST Controller。此外,我們還將演示如何通過 Swagger-UI 認證以交互式方式訪問 FooController 的受保護端點。
@RestController
@RequestMapping(value = "foos", produces = MediaType.APPLICATION_JSON_VALUE)
@OpenAPIDefinition(info = @Info(title = "Foos API", version = "v1"))
public class FooController {
@GetMapping(value = "/{id}")
public FooDTO findById(@PathVariable("id") final Long id) {
return new FooDTO(randomAlphabetic(STRING_LENGTH));
}
@GetMapping
public List<FooDTO> findAll() {
return Lists.newArrayList(new FooDTO(randomAlphabetic(STRING_LENGTH)),
new FooDTO(randomAlphabetic(STRING_LENGTH)), new FooDTO(randomAlphabetic(STRING_LENGTH)));
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public FooDTO create(@RequestBody final FooDTO fooDTO) {
return fooDTO;
}
}2.3. 用户憑據
我們將利用 Spring Security 的內存身份驗證來註冊我們的測試用户憑據:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, PasswordEncoder passwordEncoder) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder.encode("password"))
.roles("USER");
}3. 基於表單的登錄認證
讓我們看看如何認證以與我們具有表單登錄保護的文檔記錄端點進行交互。
3.1. 安全配置
在這裏,我們定義了使用 Form Login 授權請求的安全配置。
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth.requestMatchers("/v3/api-docs/**",
"/swagger-ui/**", "/swagger-ui.html")
.permitAll()
.anyRequest()
.authenticated())
.formLogin(formLogin -> formLogin.defaultSuccessUrl("/foos"));
return http.build();
}3.2. 登錄文檔
默認情況下,框架提供的登錄端點未提供文檔。因此,我們需要通過設置相應的配置屬性使其可見。此外,有用的配置屬性可以在庫的 文檔中找到:
springdoc.show-login-endpoint=true隨後,Springdoc 將檢測配置的 Spring Security 的 Form Login 並生成 Swagger-UI 中的文檔。 這樣,它將添加帶有用户名和密碼請求參數以及特定 application/x-www-form-urlencoded 請求體類型的 /login 端點:
認證成功後,我們將調用受保護的 FooController 端點。 此外,由於 defaultSucccesfulUrl 安全配置,我們從 /foos 端點獲取成功登錄的響應:
3.3. 註銷文檔
能夠進行註銷操作有助於 Swagger-UI 中的用户切換,這在某些情況下可能很有用,例如在基於角色的 API 授權應用中。
Springdoc 不提供像登錄一樣自動檢測註銷端點的功能。因此,我們需要定義一個虛假的 REST Controller,它將暴露一個 POST 請求映射到 /logout</em/> 路徑。但是,由於 Spring Security 將會攔截並處理該請求,因此我們無需添加任何實現。
@RestController
public class LogoutController {
@PostMapping("logout")
public void logout() {}
}通過添加 <em >LogoutController</em >,該庫將生成文檔並使註銷功能在 Swagger-UI 中可用:
4. 基本身份驗證
當處理帶有基本身份驗證保護的端點時,我們無需直接調用登錄功能。另一方面,OpenAPI 支持一組標準 安全方案,包括基本身份驗證,並且我們可以相應地配置 Springdoc。
4.1. 安全配置
使用基本身份驗證保護端點的一種簡單配置:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth.requestMatchers("/v3/api-docs/**",
"/swagger-ui/**", "/swagger-ui.html")
.permitAll()
.anyRequest()
.authenticated())
.httpBasic(Customizer.withDefaults());
return http.build();
}4.2. Springdoc Security Scheme
為了配置 OpenAPI 安全方案,我們需要提供基於 @SecurityScheme 註解的配置:
@Configuration
@SecurityScheme(
type = SecuritySchemeType.HTTP,
name = "basicAuth",
scheme = "basic")
public class SpringdocConfig {}然後,我們還需要為 FooController 註釋上 @SecurityRequirement(name = “basicAuth”)。 如果我們想僅保護某些端點或使用不同的方案,則可以將其註釋應用於方法級別:
@RestController
@OpenAPIDefinition(info = @Info(title = "Foos API", version = "v1"))
@SecurityRequirement(name = "basicAuth")
@RequestMapping(value = "foos", produces = MediaType.APPLICATION_JSON_VALUE)
public class FooController {
...
}因此,Swagger-UI 中將顯示“授權”按鈕。
然後,我們可以使用以下表單提供用户憑據:
隨後,調用任何 FooController 端點時,Authorization 標頭將包含帶有憑據的請求,如生成的 curl 命令所示。 這樣,我們就可以執行請求並獲得授權:
5. 結論
在本文中,我們學習瞭如何配置 Springdoc 中的身份驗證,以便通過 Swagger-UI 生成的文檔訪問受保護的端點。最初,我們通過基於表單的登錄設置進行了配置。然後,我們配置了 Basic 身份驗證方案。