Springdoc Swagger UI集成OAuth2认证

news2025/1/12 15:57:01

目录

    • 引言
    • 方式1:Bearer Token
    • 方式2:标准OAuth2授权码流程
    • 方式3:集成OIDC发现端点
    • 扩展:同时支持多种认证方式

引言

之前的文章讲过OAuth2体系,以授权码流程为例(参见下图),
其中资源服务器(Resource Server)作为服务的提供者,
用户在客户端应用完成授权流程后,客户端应用需要携带AccessToken请求资源服务器
也即是要想访问资源服务器就需要提供正确的Authorization: Bearer AccessToken
如此在将资源服务器接入Swagger UI后,是无法直接访问其后端API的,
例如直接访问会返回Http Status 401,除非在Swagger UI中接入正确的AccessToken。
在这里插入图片描述
接来下结合Springdoc & OpenAPI 3.0介绍3种支持Resource Server接入Swagger UI并支持OAuth2的方式。

注: 关于Springdoc和OpenAPI 3.0的更多说明可参见我之前的文章:
SpringBoot应用生成RESTful API文档 - Swagger 2.0、OAS 3.0、Springfox、Springdoc、Smart-doc

注:
本文Springdoc Swagger UI集成OAuth2认证示例的具体代码可参见:
https://gitee.com/luoex/spring-cloud-demo/tree/develop/api-doc-demo/springdoc-oas3-oauth2
本文使用的OAuth2 AuthServer具体代码可参见:
https://gitee.com/luoex/oauth2-auth-server-oidc/tree/main/samples/oauth2-auth-server-oidc-minimal

方式1:Bearer Token

此种方式较为简单,即直接配置Swagger UI支持自定义Bearer token,具体配置如下:
代码配置:

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.*;
import io.swagger.v3.oas.annotations.servers.Server;


/**
 * OAS 3.0 配置
 *
 * @author luohq
 * @date 2023-02-26
 */
@OpenAPIDefinition(
        info = @Info(
                title = "Springdoc OAS3.0 - OAuth2 Resource Server - RESTful API",
                description = "Springdoc OAS3.0 - OAuth2 Resource Server - RESTful API",
                version = "v1"
        ),
        servers = {@Server(url = "http://springdoc-resource-server:8080")},
        security = @SecurityRequirement(name = "Bearer access_token")
)
@SecurityScheme(
        name = "Bearer access_token",
        type = SecuritySchemeType.HTTP,
        in = SecuritySchemeIn.HEADER,
        scheme = "bearer",
        description = "直接将有效的access_token填入下方,后续该access_token将作为Bearer access_token"
)
public class OpenApiBearerConfig {
}

设置Resource Server的Swagger-UI访问Host为:
http://springdoc-resource-server:8080
启动后访问Swagger UI:
http://springdoc-resource-server:8080/swagger-ui/index.html

注:
本地开发调试需配置本地Host:
127.0.0.1 springdoc-resource-server
后文示例均通过该Host访问示例Swagger UI。

在这里插入图片描述
点击右侧的Authorize按钮,即可触发Swagger UI的认证流程,
在Bearer Token方式中点击Authorize按钮会弹出如下输入框:
在这里插入图片描述
在输入框中输入有效的access_token后点击下方的Authorize按钮即可完成,
之后在Swagger UI中点击Try it out -> Execute 发送测试请求时,均会携带请求头:
Authorization: Bearer {your_input_token_value}
如此便可通过Resource Server对access_token的校验,正常获得请求结果。
在这里插入图片描述

方式2:标准OAuth2授权码流程

此种方式Swagger UI作为OAuth2客户端,通过标准的授权码流程接入,
设置Resource Server的Swagger-UI访问Host为:
http://springdoc-resource-server:8080
Swagger-UI授权码回调地址为:http://{swagger-ui-host}:{port}/swagger-ui/oauth2-redirect.html
即:http://springdoc-resource-server:8080/swagger-ui/oauth2-redirect.html

切记 需在OAuth2 Client注册信息中指定该redirect_uri ,否则由Swagger-UI跳转到OAuth2 授权端点(即登录页)时报错Http 400。
在这里插入图片描述

代码配置:

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.*;
import io.swagger.v3.oas.annotations.servers.Server;


/**
 * OAS 3.0 配置
 *
 * @author luohq
 * @date 2023-02-26
 */
@OpenAPIDefinition(
        info = @Info(
                title = "Springdoc OAS3.0 - OAuth2 Resource Server - RESTful API",
                description = "Springdoc OAS3.0 - OAuth2 Resource Server - RESTful API",
                version = "v1"
        ),
        servers = {@Server(url = "http://springdoc-resource-server:8080")},
        security = @SecurityRequirement(name = "OAuth2 Flow", scopes = {"openid", "phone", "email", "profile", "roles"})
)
@SecurityScheme(
        name = "OAuth2 Flow",
        type = SecuritySchemeType.OAUTH2,
        flows = @OAuthFlows(
                authorizationCode = @OAuthFlow(
                        authorizationUrl = "${springdoc.swagger-ui.oauth.authorization-url}",
                        tokenUrl = "${springdoc.swagger-ui.oauth.token-url}",
                        scopes = {
                                //此处需根据Client注册时支持的Scopes进行配置
                                //openid,phone,email,profile,roles
                                @OAuthScope(name = "openid", description = "OpenId Connect"),
                                @OAuthScope(name = "phone", description = "手机号"),
                                @OAuthScope(name = "email", description = "电子邮件"),
                                @OAuthScope(name = "profile", description = "用户身份信息"),
                                @OAuthScope(name = "roles", description = "角色"),
                        }
                )
        ),
        description = "OAuth2授权码认证流程,<br/>根据需要选择下方的Scopes。"
)
public class OpenApiOAuth2Config {
}

application.yaml配置:

# springdoc配置
springdoc:
  swagger-ui:
    oauth:
      # 接入的Client凭证信息
      client-id: luo-oauth2-client1
      client-secret: luo-oauth2-client1-secret
      # Swagger UI上默认选中的scopes
      scopes:
        - openid
        - phone
        - email
        - profile
      #  OAuth2端点(绝对路径)
      authorization-url: http://oauth2-server:9000/oauth2/authorize
      token-url: http://oauth2-server:9000/oauth2/token

启动后访问Swagger UI:
http://springdoc-resource-server:8080/swagger-ui/index.html
点击右侧的Authorize按钮,即可触发Swagger UI的OAuth2 授权码认证流程,
在这里插入图片描述
如上图,弹框中已默认填入application.yaml中配置好的client_id和client_secret,
同时设置了Scopes的默认选中,可根据需求调整Scopes的选择,
之后点击Authorize按钮,即在新弹出的Tab页中重定向到OAuth2认证服务器端AuthServer,
在这里插入图片描述
完成登录后,AuthServer登录页会重定到Swagger UI的授权码回调处理页面:
http://springdoc-resource-server:8080/swagger-ui/oauth2-redirect.html
Swagger UI的授权码回调处理页获取授权码,并自动关闭AuthServer Tab页,
然后交由原Swagger UI页面通过授权码换取access_token:

注:
Swagger UI在浏览器端直接调用OAuth2 AuthServer的Token端点,由于两者不在同一域名下,直接调用会报CORS错误
所以需在AuthServer端设置允许Origin: http://springdoc-resource-server:8080跨域访问。

在这里插入图片描述

之后在Swagger UI中点击Try it out -> Execute 发送测试请求时,均会携带请求头:
Authorization: Bearer {access_token}
如此便可通过Resource Server对access_token的校验,正常获得请求结果。
在这里插入图片描述

方式3:集成OIDC发现端点

此种方式Swagger UI同样作为OAuth2客户端,只不过通过OIDC发现端点获取支持的OAuth2授权流程、端点URL及权限范围Scopes等,
例如测试使用的OAuth2 AuthServer提供OIDC发现端点:
http://oauth2-server:9000/.well-known/openid-configuration
其响应结果如下:

{
    //发布URI
    "issuer": "http://oauth2-server:9000",
    //授权端点
    "authorization_endpoint": "http://oauth2-server:9000/oauth2/authorize",
    //Token端点
    "token_endpoint": "http://oauth2-server:9000/oauth2/token",
    //Token端点认证方法
    "token_endpoint_auth_methods_supported": [
        "client_secret_basic",
        "client_secret_post",
        "none"
    ],
     //支持的授权流程
    "grant_types_supported": [
        "authorization_code",
        "client_credentials",
        "refresh_token"
    ],
     //支持的授权范围
    "scopes_supported": [
        "openid"
    ],

    "jwks_uri": "http://oauth2-server:9000/oauth2/jwks",
    "userinfo_endpoint": "http://oauth2-server:9000/userinfo",
    "response_types_supported": [
        "code"
    ],   
    "subject_types_supported": [
        "public"
    ],
    "id_token_signing_alg_values_supported": [
        "RS256"
    ],   
    "end_session_endpoint": "http://oauth2-server:9000/logout"
}

如此可以识别出该AuthServer支持的授权流程包括:

  • authorization_code
  • client_credentials
  • refresh_token

相关端点URL为:

  • 授权端点 - “authorization_endpoint”: “http://oauth2-server:9000/oauth2/authorize”
  • Token端点 - “token_endpoint”: “http://oauth2-server:9000/oauth2/token”

支持的权限范围Scopes:

  • openid

具体集成的代码配置:

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.annotations.servers.Server;


/**
 * OAS 3.0 配置
 *
 * @author luohq
 * @date 2023-02-26
 */
@OpenAPIDefinition(
        info = @Info(
                title = "Springdoc OAS3.0 - OAuth2 Resource Server - RESTful API",
                description = "Springdoc OAS3.0 - OAuth2 Resource Server - RESTful API",
                version = "v1"
        ),
        servers = {@Server(url = "http://springdoc-resource-server:8080")},
        security = @SecurityRequirement(name = "OIDC Flow", scopes = {"openid"})
)
@SecurityScheme(
        name = "OIDC Flow",
        type = SecuritySchemeType.OPENIDCONNECT,
        openIdConnectUrl = "${springdoc.swagger-ui.oauth.oidc-url}",
        description = "OpenIdConnect认证流程,<br/>由OIDC发现端点自动识别支持的授权流程,<br/>根据需要选择下方的Scopes。"
)
public class OpenApiOidcConfig {
}

application.yaml配置:

# springdoc配置
springdoc:
  swagger-ui:
    oauth:
      # 接入的Client凭证信息
      client-id: luo-oauth2-client1
      client-secret: luo-oauth2-client1-secret
      # Swagger UI上默认选中的scopes
      scopes:
        - openid
      #  OIDC发现端点(绝对路径)
      oidc-url: http://oauth2-server:9000/.well-known/openid-configuration

注:
Swagger UI集成OIDC同样需要配置OAuth2 client-id和client-secret,
但仅需配置OIDC发现端点URl即可,无需同集成OAuth2模式时配置authorization-url、token-url及需要支持的Scopes,
Swagger UI可通过解析OIDC发现端点自动识别出OAuth2 AuthServer支持的授权流程、端点URL、权限范围Scopes等。

设置Resource Server的Swagger-UI访问Host为:
http://springdoc-resource-server:8080
Swagger-UI授权码回调地址为:http://{swagger-ui-host}:{port}/swagger-ui/oauth2-redirect.html
即:http://springdoc-resource-server:8080/swagger-ui/oauth2-redirect.html

同集成OAuth2模式时一样,切记 需在OAuth2 Client注册信息中指定该redirect_uri
否则由Swagger-UI跳转到OAuth2 授权端点(即登录页)时报错Http 400。

启动后访问Swagger UI:
http://springdoc-resource-server:8080/swagger-ui/index.html
点击右侧的Authorize按钮,即可触发Swagger UI的OIDC认证流程(识别出3种,选择第一条授权码流程即可),
授权码认证流程同之前方式2中流程一样,可参见之前方式2中的介绍。
在这里插入图片描述

扩展:同时支持多种认证方式

Swagger UI支持同时集成多种认证方式,例如同时支持上面提到的3中方式,具体集成如下。

代码配置:

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.*;
import io.swagger.v3.oas.annotations.servers.Server;


/**
 * OAS 3.0 配置
 *
 * @author luohq
 * @date 2023-02-26
 */
@OpenAPIDefinition(
        info = @Info(
                title = "Springdoc OAS3.0 - OAuth2 Resource Server - RESTful API",
                description = "Springdoc OAS3.0 - OAuth2 Resource Server - RESTful API",
                version = "v1"
        ),
        servers = {@Server(url = "http://springdoc-resource-server:8080")},
        //集成多种认证模式
        security = {
                @SecurityRequirement(name = "Bearer access_token"),
                @SecurityRequirement(name = "OAuth2 Flow", scopes = {"openid", "phone", "email", "profile", "roles"}),
                @SecurityRequirement(name = "OIDC Flow", scopes = {"openid"})
        }
)
@SecurityScheme(
        name = "Bearer access_token",
        type = SecuritySchemeType.HTTP,
        in = SecuritySchemeIn.HEADER,
        scheme = "bearer",
        description = "直接将有效的access_token填入下方,后续该access_token将作为Bearer access_token"
)
@SecurityScheme(
        name = "OAuth2 Flow",
        type = SecuritySchemeType.OAUTH2,
        flows = @OAuthFlows(
                authorizationCode = @OAuthFlow(
                        authorizationUrl = "${springdoc.swagger-ui.oauth.authorization-url}",
                        tokenUrl = "${springdoc.swagger-ui.oauth.token-url}",
                        scopes = {
                                //此处需根据Client注册时支持的Scopes进行配置
                                //openid,phone,email,profile,roles
                                @OAuthScope(name = "openid", description = "OpenId Connect"),
                                @OAuthScope(name = "phone", description = "手机号"),
                                @OAuthScope(name = "email", description = "电子邮件"),
                                @OAuthScope(name = "profile", description = "用户身份信息"),
                                @OAuthScope(name = "roles", description = "角色"),
                        }
                )
        ),
        description = "OAuth2授权码认证流程,<br/>根据需要选择下方的Scopes。"
)
@SecurityScheme(
        name = "OIDC Flow",
        type = SecuritySchemeType.OPENIDCONNECT,
        openIdConnectUrl = "${springdoc.swagger-ui.oauth.oidc-url}",
        description = "OpenIdConnect认证流程,<br/>由OIDC发现端点自动识别支持的授权流程,<br/>根据需要选择下方的Scopes。"
)
public class OpenApiComboConfig {
}

application.yaml配置:

# springdoc配置
springdoc:
  swagger-ui:
    oauth:
      # 接入的Client凭证信息
      client-id: luo-oauth2-client1
      client-secret: luo-oauth2-client1-secret
      # Swagger UI上默认选中的scopes
      scopes:
        - openid
        - phone
        - email
        - profile
      #  OAuth2端点(绝对路径)
      authorization-url: http://oauth2-server:9000/oauth2/authorize
      token-url: http://oauth2-server:9000/oauth2/token
      #  OIDC发现端点(绝对路径)
      oidc-url: http://oauth2-server:9000/.well-known/openid-configuration

参考:
https://swagger.io/docs/specification/authentication/openid-connect-discovery/
https://gitee.com/mirrors_OAI/OpenAPI-Specification/blob/3.0.1/versions/3.0.1.md#security-scheme-object
https://springdoc.org/
https://github.com/springdoc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/373532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JVM全面总结

JVM全面总结一.类加载子系统why 为什么要这么做&#xff1f;when 什么时候会触发加载How 怎么样进行的---加载相关---类加载器双亲委派机制沙箱安全机制---链接过程相关------初始化相关---类构造器clinit()二.运行时数据区1.方法区(永久代 元空间)(1)方法区在哪&#xff1f;(2…

数据结构基础之动态数组

目录 前言 1、Java中的数组 2、实现动态数组 2.1、基本类结构设计 2.2、添加元素 2.3、查询&修改元素 2.4、包含&搜索&删除 2.5、数组扩容 前言 今天我们来学习一下关于数据结构的一些基础知识&#xff0c;数据结构研究的是数据如何在计算机中进行组织和存…

Java高级点的知识

Java 集合框架 该框架必须是高性能的。基本集合&#xff08;动态数组&#xff0c;链表&#xff0c;树&#xff0c;哈希表&#xff09;的实现也必须是高效的。 该框架允许不同类型的集合&#xff0c;以类似的方式工作&#xff0c;具有高度的互操作性。 对一个集合的扩展和适应…

WordPress 函数:add_theme_support() 开启主题自定义功能(全面)

add_theme_support() 用于在我们的当前使用的主题添加一些特殊的功能&#xff0c;函数一般写在主题的functions.php文件中&#xff0c;当然也可以再插件中使用钩子来调用该函数&#xff0c;如果是挂在钩子上&#xff0c;那他必须挂在after_setup_theme钩子上&#xff0c;因为 i…

Spring Security OAuth2四种授权模式总结 - Mysql存储客户端信息和令牌(八)

写在前面&#xff1a;各位看到此博客的小伙伴&#xff0c;如有不对的地方请及时通过私信我或者评论此博客的方式指出&#xff0c;以免误人子弟。多谢&#xff01;如果我的博客对你有帮助&#xff0c;欢迎进行评论✏️✏️、点赞&#x1f44d;&#x1f44d;、收藏⭐️⭐️&#…

Vue3 核心模块源码解析(上)

Vue3相比大家也都有所了解&#xff0c;即使暂时没有使用上&#xff0c;但肯定也学习过&#xff01;Vue3是使用TS进行重写&#xff0c;采用了MonoRepo的管理方式进行管理&#xff0c;本篇文章我们一起来看看 Vue3的使用&#xff0c;与Vue2有什么区别&#xff0c;以及我们该如何优…

【密码学】 一篇文章讲透数字证书

【密码学】 一篇文章讲透数字证书 数字证书介绍 数字证书是一种用于认证网络通信中参与者身份和加密通信的证书&#xff0c;人们可以在网上用它来识别对方的身份。 我们在上一篇博客中介绍了数字签名的作用和原理&#xff0c;数字签名可以防止消息被否认。有了公钥算法和数字签…

史上最全面的软件测试面试题总结(接口、自动化、性能全都有)

目录 思维发散 Linux 测试概念和模型 测试计划与工具 测试用例设计 Web项目 Python基础 算法 逻辑 接口测试 性能测试 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&#xff1a;配套学习资料和视频教学 思维发散 一个球&#xff…

二叉树——二叉搜索树的最小绝对差

二叉搜索树的最小绝对差 链接 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&#xff1a; 输入&#xff1a;root [4,2,6,1,3] 输出&#xff1a;1 示例 2&…

PowerDesigned16连接Oracle出现“Could not initialize JavaVM“时的解决步骤

PowerDesigned需要连接到数据库&#xff0c;我使用的是oracle&#xff0c;但总是连接不上&#xff0c;输出栏提示"Could not initialize JavaVM"。 经过查找资料&#xff0c;发现是PowerDesigned16是32位的&#xff0c;只能使用32位的JDK来运行JDBC驱动&#xff0c;…

如何从零开始系统的学习项目管理?

经常会有人问&#xff0c;项目管理到底应该学习一些什么&#xff1f;学习考证之后能得到什么价值&#xff1f; 以下我就总结一下内容 一&#xff0c;学习项目管理有用吗&#xff1f; 有效的项目管理带来的益处大致包括以下几个方面&#xff1a;更有效达成业务目标、满足相关…

人工智能轨道交通行业周刊-第35期(2023.2.20-2.26)

本期关键词&#xff1a;重庆智慧轨道、智能运维主机、标准轨距、地方铁路公报、景深、机器视觉应用 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通Rai…

第12天-商品维护(发布商品、商品管理、SPU管理)

1.发布商品流程 发布商品分为5个步骤&#xff1a; 基本信息规格参数销售属性SKU信息保存完成 2.发布商品-基本信息 2.1.会员等级-会员服务 2.1.1.会员服务-网关配置 在网关增加会员服务的路由配置 - id: member_routeuri: lb://gmall-memberpredicates:- Path/api/member/…

学习python第一天---前缀和

一、3956.截断数组&#xff08;前缀和&#xff09;二、前缀和&#xff08;前缀和&#xff09;[0]list(map(int,input().split()))三、子矩阵的和&#xff08;前缀和&#xff09;range(1,n1)四、K倍区间&#xff08;前缀和&#xff09;五、激光炸弹&#xff08;前缀和&#xff0…

模型部署笔记

目录模型部署工作ONNX存在的意义ONNX&#xff08;Open Neural Network Exchange&#xff09;ONNX示例模型推理示例Batch调整量化量化方式常见问题模型部署工作 训练好的模型在特定软硬件平台下推理针对硬件优化和加速的推理代码 训练设备平台&#xff1a; CPU、GPU、DSP ONN…

2023.02.26 学习周报

文章目录摘要文献阅读1.题目2.摘要3.介绍4.模型4.1 SESSION-PARALLEL MINI-BATCHES4.2 SAMPLING ON THE OUTPUT4.3 RANKING LOSS5.实验5.1 数据集5.2 验证方式5.3 baselines5.4 实验结果6.结论深度学习元胞自动机1.定义2.构成3.特性4.思想5.统计特征流形学习1.降维2.空间3.距离…

一些硬件学习的注意事项与快捷方法

xilinx系列软件 系统适用版本 要安装在Ubuntu系统的话&#xff0c;要注意提前看好软件适用的版本&#xff0c;不要随便安好了Ubuntu系统又发现对应版本的xilinx软件不支持。 如下图&#xff0c;发行说明中会说明这个版本的软件所适配的系统版本。 下载 vivado vitis这些都可以…

IT男的一次中年破局尝试--出书

一、转战外企 接上回《人到中年——IT男择业感悟》后&#xff0c;自己从大央企去了某知名外企。外企虽然最近几年的日子已经没有10年前的辉煌与滋润&#xff0c;但相对来说&#xff0c;还能勉强找到工作与生活的平衡点。 划重点&#xff0c;35岁上下的人换工作理由&#xf…

SpringBoot+React博客论坛系统 附带详细运行指导视频

文章目录一、项目演示二、项目介绍三、项目运行截图四、主要代码一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootReact框架开发的博客论坛系统。首先&#xff0c;这是一个前后端分离的项目&#xff0c;文章编辑器…

大学物理期末大题专题训练总结-磁学大题

&#xff08;事先声明指的是简单的那个磁学大题&#xff0c;另外一类涉及储存的磁能、磁感应强度分布下次说&#xff09;求个磁通量&#xff0c;求个感应电动势&#xff0c;求个安培力大小......这个感觉是不是像你梦回高中&#xff1f;当然&#xff0c;这一块大题跟高中磁学部…