Spring Cloud Gateway集成Swagger实现微服务接口文档统一管理及登录访问

news2025/1/16 9:00:26

简介

本文将介绍如何在Spring Cloud微服务中使用Swagger网关来统一管理所有微服务的接口文档,并通过Spring Security实现登录后才能访问Swagger文档,以确保接口数据的安全访问。

在开始之前,需要假设你已经完成了Spring Cloud Gateway的相关配置,并且已经了解了基本的网关配置知识。本文将不再赘述Gateway的配置,只介绍在此基础上如何配置Swagger来管理所有微服务,并通过账号密码来管理Swagger的访问。

一.网关中需要引入swagger依赖

本教程spring boot版本为2.0.9.RELEASE,spring cloud版本为Finchley.SR4

引入swagger pom依赖:

<dependency>
	<groupId>com.spring4all</groupId>
	<artifactId>swagger-spring-boot-starter</artifactId>
	<version>2.0.2</version>
</dependency>

二.通过Swagger配置类,获取所有微服务文档

此类会在访问swagger ui时调用,来获取所有swagger resources资源,包括了所有微服务的接口文档地址。

package cn.demo.conf;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider {

	/**
	 * swagger2默认的url后缀(v2或v3)
	 */
	private static final String SWAGGER2URL = "/v2/api-docs";

	/**
	 * 网关路由
	 */
	@Resource
	private final RouteLocator routeLocator;


	/**
	 * 汇总所有微服务的swagger文档路径(访问swagger页面时,会调用此方法获取docs)
	 *
	 * @return
	 */
	@Override
	public List<SwaggerResource> get() {
		List<SwaggerResource> resources = new ArrayList<>();
		// 从网关路由中获取所有服务的host名
		List<String> routeHosts = new LinkedList<>();
		routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null)
				.subscribe(route -> routeHosts.add(route.getUri().getHost()));
		// 将文档列表排序,服务多的时候以免显得混乱
		Collections.sort(routeHosts);
		// 不需要展示Swagger的服务列表,在swagger ui页面右上角下拉框中,将不再展示(改成你自己不需要展示的服务)
		List<String> ignoreServers = Arrays
				.asList( "sever1", "server2");
		// 记录已经添加过的微服务(有些服务部署多个节点,过滤掉重复的)
		List<String> docsUrls = new LinkedList<>();
		for (String host : routeHosts) {
			if (ignoreServers.contains(host) ) {
				//排除忽略服务名
				continue;
			}
			// 拼接swagger docs的url,示例:/server1/v2/api-docs
			String url = "/" + host + SWAGGER2URL;
			// 排除掉重复
			if (!docsUrls.contains(url)) {
				docsUrls.add(url);
				SwaggerResource swaggerResource = new SwaggerResource();
				swaggerResource.setUrl(url);
				swaggerResource.setName(host);
				resources.add(swaggerResource);
			}
		}
		return resources;
	}
}

上述代码中,ignoreServers 为忽略服务的列表,我们通过网关路由,可以将所有经过网关管理甚至注册到同一个注册中心的服务都能获取到,但有些服务是不需要提供接口的,或者不需要展示swagger文档,我们可以在此列表中将其排除,排除后的服务不再显示在swagger UI 页面中,如下图:
在这里插入图片描述

三.通过swagger controller增加获取swagger资源和配置的接口

此类逻辑不需要修改,直接复制即可:

package cn.demo.controller;

import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;

@RestController
public class SwaggerHandlerController {

    @Autowired(required = false)
    private SecurityConfiguration securityConfiguration;

    @Autowired(required = false)
    private UiConfiguration uiConfiguration;

    private final SwaggerResourcesProvider swaggerResources;

    @Autowired
    public SwaggerHandlerController(SwaggerResourcesProvider swaggerResources) {
        this.swaggerResources = swaggerResources;
    }


    @GetMapping("/swagger-resources/configuration/security")
    public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("/swagger-resources/configuration/ui")
    public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("/swagger-resources")
    public Mono<ResponseEntity> swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }

    // @GetMapping("/")
    public Mono<ResponseEntity> swaggerResourcesN() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }

    //@GetMapping("/csrf")
    public Mono<ResponseEntity> swaggerResourcesCsrf() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}

四.网关的路由配置中透传所有swagger资源地址

这个地方大家需要根据自己网关内容进行配置了,每个人的网关中,都有些URL需要透传,即不需要网关做拦截,那么把swagger 服务名进行透传即可。

举例:
swagger需要通过http://10.1.1.1:88/server1/v2/api-docs来获取server1微服务的接口文档,那么如果你网关拦截了此路径,那么swagger就无法显示此文档了。所有我们需要让网关放行此路径。默认网关是放行的,但有些网关会把所有接口返回值进行封装,所以就需要透传。
格式示例:
String ignoreUrl = "/server1/**";

配置完了这些,如果你各个微服务中接口,已经加上了swagger注解的话,那么就可以启动网关,来测试下是否能访问swagger了,网关地址示例:http://10.1.1.1:88/swagger-ui/index.html,将ip和端口换成你自己的即可。

五.给Swagger增加用户名密码登陆,保证文档安全

这一步是可选的,生产环境我们一般是不允许使用swagger 的,但如果你们公司对接口文档安全要求严格的话,甚至开发环境都要加密可以继续下面的配置,来实现当你访问swagger之前,需要先登录。
在这里插入图片描述

1.添加Spring Security依赖和webFlux依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
	<version>2.5.15</version>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-webflux</artifactId>
	<exclusions>
		<exclusion>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-logging</artifactId>
		</exclusion>
		<exclusion>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
		</exclusion>
	</exclusions>
</dependency>

2.增加Spring security配置类

由于spring cloud gateway是一个spring-boot-starter-webflux项目,不是spring-boot-starter-web项目,所以需要用webFlux实现路径拦截,写法与web项目类似。

package cn.demo.conf;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;

/**
 * @description: spring security路径拦截器
 * @author: 大脑补丁
 * @create: 2023-08-18 16:34
 */
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

	@Value("${swagger.username}")
	private String username;
	@Value("${swagger.password}")
	private String password;

	@Bean
	public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
		return http
				.authorizeExchange()
				.pathMatchers("/swagger-ui/index.html").authenticated()
				.pathMatchers("/swagger-resources/**").authenticated()
				.pathMatchers("/v2/api-docs").authenticated()
				.pathMatchers("/v3/api-docs").authenticated()
				.pathMatchers("/webjars/**").authenticated()
				.pathMatchers("/actuator/**").authenticated()
				.anyExchange().permitAll()
				.and()
				.formLogin()
				.and()
				.logout()
				.and()
				.csrf().disable()
				.build();
	}

	@Bean
	public PasswordEncoder passwordEncoder() {
		return  NoOpPasswordEncoder.getInstance();
	}

	@Bean
	public MapReactiveUserDetailsService userDetailsService() {
		UserDetails user = User.withUsername(username)
				.password(password)
				.roles("USER")
				.build();
		return new MapReactiveUserDetailsService(user);
	}
}

在配置文件中,配置下需要登陆的用户名密码:

#swagger登录用户名密码
swagger.username=admin
swagger.password=123456

配置完成后,当你再次访问swagger页面时,会先跳转到login页面,登陆成功后,会自动跳转到登陆页面。

六.总结

本文讲解了Spring Cloud Gateway统一管理所有微服务Swagger文档,并支持登陆后才能访问。其中主要用到的步骤都已交代,大家可以根据自己的网关配置,将其兼容进去即可。喜欢本文请点赞收藏。

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

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

相关文章

触控笔哪个牌子好用?主动电容笔和被动电容笔的区别

主动式电容笔和被动式电容笔两者最大的不同之处在于主动式电容笔的应用范围更大&#xff0c;可以兼容各种不同的电容屏幕。随着人们对其认识的不断深入&#xff0c;其应用范围也在不断扩大。而且国产的主动式电容笔&#xff0c;也在不断的更新换代&#xff0c;重力越来越多&…

【工具】SecureCR-8.5下载、安装激活和使用教程

起初我参考的文章&#xff1a;【工具】SecureCR-8.5下载、安装激活和使用教程&#xff08;包含常用设置&#xff09;_securecrt激活_SecureCode的博客-CSDN博客 但是不行啊&#xff0c;执行到13步的时候报错&#xff1a; 问了作者也没有回应&#xff0c;直到我参考了&#xff…

动手实现H5仿原生app前进后退切换效果

动手实现H5仿原生app前进后退切换效果 前言 最近在优化H5页面&#xff0c;我注意到当开发完成的移动端H5页面嵌入到微信小程序或者原生app中时&#xff0c;当触发页面路由切换会与原生app看上去有点格格不入&#xff0c;因为H5页面<router-view>切换路由时是直接替换了…

vue3点击表格某个单元格文本就切换成输入框,其他单元格不变化

<el-table :data"data.tableData" height"60vh" border scrollbar-aways-on><el-table-column label"序号" type"index" width"80" fixed /><el-table-column label"操作" width"120" f…

Linux知识点 -- 高级IO(二)

Linux知识点 – 高级IO&#xff08;二&#xff09; 文章目录 Linux知识点 -- 高级IO&#xff08;二&#xff09;一、IO多路转接 -- poll1.poll接口2.poll实现3.poll优缺点 二、IO多路转接 -- epoll1.epoll接口2.epoll的工作原理3.epoll服务器实现4.epoll的优点5.epoll的工作模式…

在线加解密(支持SM2、SM3、SM4)

https://the-x.cn/zh-cn/cryptography/Sm4.aspx

SAS国际认证考试报名流程

文章目录 注册SAS账号登录SAS账号预约考试考试注意事项 注册SAS账号 SAS考试报名入口&#xff1a;https://home.pearsonvue.com/sas 注册SAS账号 邮箱验证 点击上述邮件发送来的链接&#xff0c;跳转到如下界面。输入密码即可。 完成注册。选择login。 登录SAS账号 输入Email …

MongoDB 未授权访问漏洞

简介 MongoDB是一个基于分布式文件存储的数据库&#xff0c;是一个介于关系数据库和非关系数据库之间的产品&#xff0c;它的特点是高性能、易部署、易使用&#xff0c;存储数据非常方便&#xff0c;默认情况下是没有认证的这就导致不熟悉它的研发人员部署后没有做访问控制导致…

NAND存储器转储分析 - 使用ECC修复位错误与UBI镜像固件分析

一、 简介 这篇研究论文将通过黑客的视角&#xff0c;详细阐述如何操作 NAND dump 以及如何获取 dump 文件中的所有文件。每一步骤以及所使用的方法均会细致解析&#xff0c;并配以实例说明。本文主要关注的是物理 NAND dump&#xff0c;这是从通用编程器中提取出的 dump 文件…

重磅!中科院1区TOP被踢?共7本被剔除!10月SCIE/SSCI期刊目录更新!

期刊动态&#xff1a;2023年10月SCI、SSCI期刊目录更新 2023年10月17日&#xff0c;科睿唯安更新了WOS期刊目录&#xff0c;继上次9月WOS期刊目录剔除7本SCIE&SSCI期刊之后&#xff0c;此次10月更新又有7本期刊发生变动&#xff0c;其中有5本SCIE期刊&#xff0c;1本SSCI期…

软键盘怎么打开?3招快速打开!

“我的键盘好像出现了一些问题&#xff0c;现在没法输入文字。听说电脑上有个工具叫软键盘&#xff0c;我想暂时先用这个来代替键盘。有什么方法可以把它打开的吗&#xff1f;” 软键盘是一个虚拟键盘&#xff0c;它不是物理键盘&#xff0c;而是出现在计算机屏幕上的可视化输入…

java的注解接口Target

java.lang.annotation.Target是Java中预定义的一个注解接口&#xff0c;用在注解接口的声明上&#xff0c;指明注解接口适用的上下文。 Target注解接口只有一个元素value&#xff0c;该元素的类型是java.lang.annotation.ElementType的数组&#xff0c;其中ElementType是一个枚…

vue使用pdf 导出当前页面,(jspdf, html2canvas )

需要安装两个插件 npm install html2canvas jspdfyarn add html2canvas jspdf<div class"app-container" id"pdfPage">我是内容 </div><el-button size"mini" click"onExportPdf">导出数据</el-button>onexp…

SAP MM物料移动取总账科目逻辑,debug 标准bapi BAPI_GOODSMVT_CREATE

debug 标准bapi BAPI_GOODSMVT_CREATE perform mb_create_goods_movement function MB_CREATE_GOODS_MOVEMENT function MB_CREATE_MATERIAL_DOCUMENT perform buchen_aufbereiten perform F-SEGMENTE_GENERIEREN perform f-segmente_erstellen perform f-segmente_erzeugen p…

C语言参悟-函数

C语言参悟-函数 一、概述二、函数1. 函数的构成2. 函数参数3. 函数名4. 函数返回值5. 函数的工作1. 程序栈2、栈帧的组织 三、函数递归四、函数指针 一、概述 首先&#xff0c;什么是函数&#xff1f;函数&#xff08;function&#xff09;是完成特定任务的独立程序代码单元。…

五金仓库管理员的工作内容

近几年来&#xff0c;很多企业会发现&#xff0c;经营增长的压力越来越大&#xff0c;主要原因包括外部局势的巨变&#xff0c;市场捉摸不定&#xff1b;企业之间竞争越来越剧烈&#xff0c;企业的利润空间不断被压缩&#xff1b;员工越来越个性化、多元化&#xff0c;管理困难…

文档外发控制与安全:实现高效协作与数据安全的关键

随着企业数据量的不断增加&#xff0c;文档外发成为了一个不可避免的需求。然而&#xff0c;很多企业在文档外发过程中存在着很多问题&#xff0c;如数据泄露、信息误用等。因此&#xff0c;如何保证文档外发的安全性和高效性成为了企业亟待解决的问题。飞驰云联Ftrans的文件收…

软件工程与计算(十四)详细设计中面向对象方法下的模块化

一.面向对象中的模块 1.类 模块化是消除软件复杂度的一个重要方法&#xff0c;每个代码片段相互独立&#xff0c;这样能够提高可维护性。在面向对象方法中&#xff0c;代码片段最重要的类&#xff0c;整个类的所有代码联合起来构成独立的代码片段。 模块化希望代码片段由两部…

以烟草行业为例,聊聊如何基于 PLC + OPC + TDengine,快速搭建工业生产监测系统

在烟草工业场景里&#xff0c;多数设备的自动控制都是通过 PLC 可编程逻辑控制器来实现的&#xff0c;PLC 再将采集的数据汇聚至 OPC 服务器。传统的 PI System、实时数据库、组态软件等与 OPC 相连&#xff0c;提供分析、可视化、报警等功能&#xff0c;这类系统存在一些问题&…

Tortoise SVN 察看本地缓存密码

1、打开设置&#xff08;Settings&#xff09; 2、查看保存的数据 3、打开鉴权数据 4、查看密码 CTRLSHIFT双击表格&#xff0c;就会出现一列密码列 &#xff08;我的是Mac PD虚拟Win11&#xff0c;CTRLSHIFTOPTION双击表格&#xff09; 原文见这里&#xff1a; Recover SVN …