1、概览 {#1概览}
Springdoc-OpenAPI 是一个为 Spring Boot 应用程序自动生成 API 文档的框架。它实现了 OpenAPI 3 规范,使用它,通过 UI 界面就可以与 API 进行交互,非常方便。
在本教程中,我们将学习如何使用 Spring Security 通过表单登录和 Basic Authentication 来认证 springdoc 中的端点访问。
2、项目设置 {#2项目设置}
创建一个 Spring Boot Web 应用程序,该应用程序将通过 Spring Security 保护 API,并使用 Springdoc 生成文档。
2.1、依赖 {#21依赖}
首先添加 springdoc-openapi-ui
,它整合了 Swagger-UI,用于提供 UI 界面:
http://localhost:8080/swagger-ui.html
其次,添加 springdoc-openapi-security,用于为 Spring Security 提供支持:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.13</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
<version>1.6.13</version>
</dependency>
2.2、示例 API {#22示例-api}
创建一个示例 REST Controller,Springdoc 会为其生成文档。
此外,我们将通过 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、用户凭证 {#23用户凭证}
我们使用 Spring Security 的内存认证(inMemoryAuthentication),来注册我们测试用户的凭证信息:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, PasswordEncoder passwordEncoder) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder.encode("password"))
.roles("USER");
}
3、基于表单的登录认证 {#3基于表单的登录认证}
让我们看看,如何使用基于表单的登录认证,来与受保护的端点进行交互。
3.1、Security 配置 {#31security-配置}
定义 Security 配置,指定需要使用表单登录来进行认证的请求:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/v3/api-docs/**",
"/swagger-ui/**",
"/swagger-ui.html").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/foos");
return http.build();
}
3.2、登录文档 {#32登录文档}
默认情况下,框架提供的登录端点不会在文档中显示。需要修改其配置: 可以在官方 文档 中找到完整可用的配置属性。
springdoc.show-login-endpoint=true
随后,Springdoc 将检测已配置的 Spring Security 表单登录,并在 Swagger-UI 中生成文档。如下,它添加了一个 /login
端点,请求类型是 application/x-www-form-urlencoded
,参数是 username
和 password
:
通过身份认证后,我们就可以调用 FooController
端点了。此外,由于 defaultSucccesfulUrl
配置,我们会从 /foos
端点获取成功登录的响应:
3.3、注销文档 {#33注销文档}
注销功能用于在 Swagger-UI 中进行用户切换。
Springdoc 并不像登录那样提供自动检测注销端点的方法。在这种情况下,我们需要定义一个 REST Controller,为 /logout
路径提供请求映射。不过,我们不需要进行任何实现,因为 Spring Security 会拦截并处理请求:
@RestController
public class LogoutController {
@PostMapping("logout")
public void logout() {}
}
添加 LogoutController
后,框架将会为其将生成文档并在 Swagger-UI 中提供注销功能:
4、Basic Authentication {#4basic-authentication}
在请求 Basic Authentication (基础认证)端点时,不需要直接调用登录。
另外,OpenAPI 支持包括 Basic Authentication 在内的一系列标准 security scheme,我们可以据此配置 Springdoc。
4.1、Security Configuration {#41security-configuration}
简单的安全配置,使用 Basic Authentication 保护端点:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/v3/api-docs/**",
"/swagger-ui/**",
"/swagger-ui.html").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
return http.build();
}
4.2、Springdoc Security Scheme {#42springdoc-security-scheme}
要配置 OpenAPI Security Scheme,我们需要在配置类上使用 @SecurityScheme
注解进行配置:
@Configuration
@SecurityScheme(
type = SecuritySchemeType.HTTP,
name = "basicAuth",
scheme = "basic")
public class SpringdocConfig {}
然后,还必须用 @SecurityRequirement(name = "basicAuth")
注解FooController
。也可以在方法级别应用此注解,表示此认证方式只对该方法生效:
@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
Header 会被自动包含在请求中,如下图中生成的 curl
命令所示:
5、总结 {#5总结}
在本文中,我们学习了如何在 Springdoc 文档中配置身份认证,以访问受保护的端点。
我们介绍了基于表单和 Basic Authentication 的认证方式。
参考:https://www.baeldung.com/springdoc-openapi-form-login-and-basic-authentication