给 OpenAPI 配置 JWT Authentication(认证)

1、概览

OpenAPI 是一种与语言无关且独立于平台的规范,用于标准化 REST API。OpenAPI 使用户能够在不深入代码的情况下轻松理解 API。

Swagger-UI 根据 OpenAPI 规范生成可视化文档,帮助可视化和测试 REST API。

本文将带你了解如何在 Spring Boot 应用中使用 Springdoc-OpenAPI 生成 OpenAPI 文档、测试 REST API 并为 OpenAPI 配置 JWT Authentication(认证)。

2、Swagger-UI

Swagger-UI 是 HTML、Javascript 和 CSS 文件的集合,可根据 OpenAPI 规范生成 UI 界面。

当 API 数量不断增加时,编写 OpenAPI 文档规范就变得非常具有挑战性。Springdoc-OpenAPI 可以帮助我们自动生成 OpenAPI 文档。

接下来,我们通过示例了解如何使用 Springdoc-OpenAPI 库自动生成 REST API 的 OpenAPI 文档,并使用 Swagger-UI 可视化这些 API。

2.1、依赖

首先,添加 Springdoc-OpenAPI 依赖。

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

此依赖还将 Swagger-UI web-jar 添加到 Spring Boot 应用中。

2.2、配置

启动应用,打开浏览器访问:http://localhost:8080/swagger-ui.html

你可以看到 Swagger-UI 页面:

Swagger UI 主页

OpenAPI v3.0 文档可以通过 http://localhost:8080/v3/api-docs 访问。

使用 @OpenAPIDefinitionUser API 添加说明、服务条款和其他元信息:

@Configuration
@OpenAPIDefinition(
  info =@Info(
    title = "User API",
    version = "${api.version}",
    contact = @Contact(
      name = "Baeldung", email = "user-apis@baeldung.com", url = "https://www.baeldung.com"
    ),
    license = @License(
      name = "Apache 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0"
    ),
    termsOfService = "${tos.uri}",
    description = "${api.description}"
  ),
  servers = @Server(
    url = "${api.server.url}",
    description = "Production"
  )
)
public class OpenAPISecurityConfiguration {}

还可以将配置和元信息定义在 application.propertiesapplication.yaml 文件中,如:api.versiontos.uriapi.description

2.3、测试

启动应用,并打开 Swagger-UI:http://localhost:8080/swagger-ui/index.html

swagger 配置页面

可以通过 http://localhost:8080/v3/api-docs 访问OpenAPI 文档:

{
    "openapi": "3.0.1",
    "info": {
      "title": "User API",
      "termsOfService": "terms-of-service",
     ...
     ...
}

3、JWT 认证

接着,为 OpenAPI 配置基于 JWT 认证。

我们可以按 API、类或全局级别配置 OpenAPI 的 JWT 认证。

3.1、API 级配置

声明 JWT 认证只用于特定 API。

定义配置如下:

@Configuration
@SecurityScheme(
  name = "Bearer Authentication",
  type = SecuritySchemeType.HTTP,
  bearerFormat = "JWT",
  scheme = "bearer"
)
public class OpenAPI30Configuration {}

@SecurityScheme 注解将 securitySchemes 添加到 OneAPI 规范的 components (组件)部分。@SecurityScheme 定义了 API 可以使用的安全机制。支持的安全机制有 APIKey、HTTP Authentication(Basic 和 Bearer)、OAuth2 和 OpenID Connect。

在本例中,使用 HTTP Bearer Authentication 作为安全方案。

对于基于 HTTP Bearer Token 的认证,我们需要选择安全方案为 bearerAuth,bearer 格式为 JWT

对于 API 级认证,在 API 上使用 @SecurityRequirement 注解:

@Operation(summary = "Delete user", description = "Delete user")
@SecurityRequirement(name = "Bearer Authentication")
@DeleteMapping
description = "A JWT token is required to access this API...",
public String deleteUser(Authentication authentication) {}

配置完毕后,重启应用。访问 URL http://localhost:8080/swagger-ui.html

Swagger API

单击 “🔒” 图标会打开一个登录对话框,让用户提供访问 Token 以调用 API:

Swagger 登录对话框

在本例中,可以通过向 Authentication API 提供 john/password 或 jane/password 来获取 JWT Token。获取 JWT Token 后,将其输入文本框,然后点击 “Authorize” 按钮和 “Close” 按钮。

Swagger 授权对话框

有了 JWT Token,就可以调用删除用户 API 了:

删除用户 API

如上,你可以看到 Swagger-UI 将此 Token 作为 HTTP Bearer 提供给 Authorization Header。最后,成功地调用了受保护的 deleteUser API。

3.2、类级配置

也可以为一个类中的所有 API 提供 OpenAPI 认证。

在包含所有 API 的类上声明 @SecurityRequirement 注解,为该类中的所有 API 提供认证:

@RequestMapping("/api/user")
@RestController
@SecurityRequirement(name = "bearerAuth")
@Tag(name = "User", description = "The User API. Contains all the operations that can be performed on a user.")
public class UserApi {}

假设该类有两个 API,在 Swagger-UI 中看起来就像这样:

Swagger API

3.3、全局配置

通常情况下,我们更倾向于将 OpenAPI 认证应用于应用中的所有 API。

我们可以使用 Spring @Bean 注解声明全局级别的安全配置:

@Configuration
public class OpenAPI30Configuration {
@Bean
public OpenAPI customizeOpenAPI() {
    final String securitySchemeName = "bearerAuth";
    return new OpenAPI()
      .addSecurityItem(new SecurityRequirement()
        .addList(securitySchemeName))
      .components(new Components()
        .addSecuritySchemes(securitySchemeName, new SecurityScheme()
          .name(securitySchemeName)
          .type(SecurityScheme.Type.HTTP)
          .scheme("bearer")
          .bearerFormat("JWT")));
    }
}

如上,Springdoc-OpenAPI 就能为应用中的所有 OpenAPI 配置 JWT 认证

Swagger 全局认证

尝试调用 GET API:

Swagger API 401 响应

API 返回了 “HTTP 401 Unauthorized。API”,这是因为未提供 Token,API 是受保护的。接下来,提供 JWT Token 并重新发起请求。

点击 “Authorize” 按钮并提供 JWT Token 以调用 API。我们可以从 swagger 控制台中提供的 Authentication API 获取 Bearer Token:

Swagger 获取 Bearer Token

配置好 JWT Token 后,重新调用 API:

Swagger 调用 API

此时,有了正确的 JWT Token,就可以成功调用受保护的 API 了。

4、总结

本文介绍了如何为 OpenAPI 配置 JWT 认证。Swaggerdoc-OpenAPI 基于 Spring Boot 应用中的 REST API 生成 OneAPI 规范。Swagger-UI 可以根据 OneAPI 规范对 REST API 生成文档和进行测试。


参考:https://www.baeldung.com/openapi-jwt-authentication