gateway+swagger+security实现

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 Tair(兼容Redis),内存型 2GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: gateway+swagger+security实现
  • 项目结构如下:
    |---- parent-base
        |---- auth-service
        |---- system-service
        |---- gateway-service
    
一、parent-base

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
    </parent>

    <groupId>com.test</groupId>
    <artifactId>parent-base</artifactId>
    <version>0.0.1</version>
    <name>test</name>
    <description>测试</description>
    <packaging>pom</packaging>

    <modules>
        <module>system_service</module>
        <module>gateway_service</module>
        <module>auth_service</module>
    </modules>

    <properties>
        <main.version>0.0.1</main.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-boot.version>2.2.6.RELEASE</spring-boot.version>
        <spring-feign.version>2.2.2.RELEASE</spring-feign.version>
        <spring-cloud.version>Hoxton.SR4</spring-cloud.version>
        <spring-boot-admin.version>2.2.3</spring-boot-admin.version>
        <spring-boot.mybatis>2.1.2</spring-boot.mybatis>
        <nacos.version>1.3.0</nacos.version>
        <swagger.fox.version>2.9.2</swagger.fox.version>
        <swagger.core.version>1.5.24</swagger.core.version>
        <swagger.bootstrap.version>1.9.6</swagger.bootstrap.version>
        <knife4j.version>2.0.5</knife4j.version>
        <pagehelper.boot.version>1.2.12</pagehelper.boot.version>
        <commons.io.version>2.5</commons.io.version>
        <commons.fileupload.version>1.3.3</commons.fileupload.version>
        <velocity.version>1.7</velocity.version>
        <fastjson.version>1.2.73</fastjson.version>
        <poi.version>3.17</poi.version>
        <common-pool.version>2.6.2</common-pool.version>
        <druid.version>1.1.10</druid.version>
        <commons-collections4.version>4.2</commons-collections4.version>
        <mysql.connector.version>8.0.19</mysql.connector.version>
        <feign-httpclient.version>10.7.4</feign-httpclient.version>
        <easyexcel.version>2.1.3</easyexcel.version>

    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <!--Spring boot Redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <!-- 依赖声明 -->
    <dependencyManagement>
        <dependencies>

            <!-- SpringCloud 微服务 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- SpringCloud Alibaba 微服务 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Alibaba Nacos 配置 -->
            <dependency>
                <groupId>com.alibaba.nacos</groupId>
                <artifactId>nacos-client</artifactId>
                <version>${nacos.version}</version>
            </dependency>

            <!-- SpringBoot 依赖配置 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--  SpringBoot 监控客户端 -->
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-starter-client</artifactId>
                <version>${spring-boot-admin.version}</version>
            </dependency>

            <!-- Mybatis 依赖配置 -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${spring-boot.mybatis}</version>
            </dependency>

            <!-- SpringBoot openfeign -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>${spring-feign.version}</version>
            </dependency>

            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-httpclient</artifactId>
                <version>${feign-httpclient.version}</version>
            </dependency>

            <!-- swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger.fox.version}</version>
            </dependency>
            <!-- swagger2-UI-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger.fox.version}</version>
            </dependency>

            <!--knife4j-swagger文档增强-->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>${knife4j.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>swagger-bootstrap-ui</artifactId>
                <version>${swagger.bootstrap.version}</version>
            </dependency>

            <!-- pagehelper 分页插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.boot.version}</version>
            </dependency>

            <!-- io常用工具类 -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons.io.version}</version>
            </dependency>

            <!-- excel工具 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>

            <!-- 文件上传工具类 -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${commons.fileupload.version}</version>
            </dependency>

            <!-- JSON 解析器和生成器 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>${easyexcel.version}</version>
            </dependency>

            <!-- 公共资源池 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
                <version>${common-pool.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>           

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.connector.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
一、auth-service

pom.xml中导入相关jar包

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!-- SpringCloud Ailibaba Nacos Config -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    <!-- SpringBoot Actuator -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!-- SpringBoot mybatis -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>

    <!-- SpringBoot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Mysql Connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
    </dependency>

    <!-- swagger2-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <exclusions>
            <exclusion>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-annotations</artifactId>
            </exclusion>
            <exclusion>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-models</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-annotations</artifactId>
        <version>1.5.21</version>
    </dependency>
    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-models</artifactId>
        <version>1.5.21</version>
    </dependency>

    <!-- swagger2-UI-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
    </dependency>

    <!--knife4j-swagger文档增强-->
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>knife4j-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>swagger-bootstrap-ui</artifactId>
    </dependency>

</dependencies>

配置bootstrap.yml

# Tomcat
server:
  port: 8084
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # tomcat最大线程数,默认为200
    max-threads: 800
    # Tomcat启动初始化的线程数,默认值25
    min-spare-threads: 30

# Spring
spring:
  profiles:
    active: dev 
  application:
    # 应用名称
    name: auth-service
  main:
    #当遇到相同名字时,是否允许覆盖注册
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 配置文件格式
        file-extension: yaml

# swagger开启控制
swagger:
  enable: true

#  log
logging:
  level:
    root: INFO
    org.mybatis: DEBUG

swagger配置类SwaggerConfig

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.List;

import static com.google.common.collect.Lists.newArrayList;

/**
 * <p>Swagger的初始化配置</p>
 *
 * @Author bob
 * @Date 2020/9/21 12:51
 */
@EnableSwagger2
@Configuration
public class SwaggerConfig {
   
   

    @Value("${swagger.enable}")
    private boolean enableSwagger;

    /**
     * 创建API应用
     * apiInfo() 增加API相关信息
     * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
     * 本例采用指定扫描的包路径来定义指定要建立API的目录。
     * @return
     */
    @Bean
    public Docket createRestApi() {
   
   
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(enableSwagger)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.test.controller"))
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    /**
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     * 访问地址:http://项目实际地址/swagger-ui.html
     * @return
     */
    private ApiInfo apiInfo() {
   
   
        return new ApiInfoBuilder()
                .title("测试 RESTful APIs")
                .description("测试 RESTful APIs")
                .termsOfServiceUrl("")
                //.license("证书")
                //.licenseUrl("证书地址")
                .version("1.0")
                .build();
    }

    private List<ApiKey> securitySchemes() {
   
   
        return newArrayList(
                new ApiKey("Authorization","Authorization","header"));
    }

    private List<SecurityContext> securityContexts() {
   
   
        return newArrayList(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .forPaths(PathSelectors.any())
                        .build()
        );
    }

    List<SecurityReference> defaultAuth() {
   
   
        AuthorizationScope authorizationScope = new AuthorizationScope("global","accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return newArrayList(
                new SecurityReference("Authorization",authorizationScopes));
    }
}

启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * <p>权限鉴定管理</p>
 *
 * @Author bob
 * @Date 2020/9/18 11:39
 */
@SpringBootApplication(exclude = {
   
   DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
public class AuthApplication {
   
   
    public static void main(String[] args) {
   
   
        SpringApplication.run(AuthApplication.class, args);
        System.out.println("权限鉴定服务启动成功");
    }
}

二、system-service

pom.xml中导入相关jar包

<dependencies>
    <!-- SpringCloud Ailibaba Nacos -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!-- SpringCloud Ailibaba Nacos Config -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    <!-- SpringBoot Actuator -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!-- SpringBoot mybatis -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>

    <!-- SpringBoot openfeign -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>

    <!-- SpringBoot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Pagehelper -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
    </dependency>

    <!-- swagger2-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <exclusions>
            <exclusion>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-annotations</artifactId>
            </exclusion>
            <exclusion>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-models</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-annotations</artifactId>
        <version>1.5.21</version>
    </dependency>
    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-models</artifactId>
        <version>1.5.21</version>
    </dependency>

    <!-- swagger2-UI-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
    </dependency>

    <!--knife4j-swagger文档增强-->
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>knife4j-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>swagger-bootstrap-ui</artifactId>
    </dependency>

    <!-- Mysql Connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
    </dependency>

</dependencies>

配置bootstrap.yml

# Tomcat
server:
  port: 8081
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # tomcat最大线程数,默认为200
    max-threads: 800
    # Tomcat启动初始化的线程数,默认值25
    min-spare-threads: 30

# Spring
spring:
  application:
    # 应用名称
    name: system-service
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 配置文件格式
        file-extension: yaml
  datasource:
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/cultural_cloud?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai
      password: root
      username: root
      dbcp2:
       min-idle: 5                         # 数据库连接池的最小维持连接数
       initial-size: 5                     # 初始化连接数
       max-total: 5                        # 最大连接数
       max-wait-millis: 150                # 等待连接获取的最大超时时间
  # 服务模块
  devtools:
    restart:
      # 热部署开关
      enabled: true
  # redis 配置
  redis:
    # 地址
    host: 127.0.0.1
    # 端口,默认为6379
    port: 6379
    # 密码
    password:
    # 连接超时时间
    timeout: 10s
    lettuce:
      pool:
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池的最大数据库连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
  #spring-boot中对于@RestController或者@Controller+@ResponseBody注解的接口方法的返回值默认是Json格式,
  #所以当对于date类型的数据,在返回浏览器端是会被spring-boot默认的Jackson框架转换,
  #对返回的数据包含Date类型的json进行格式化处理
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

# swagger开启控制
swagger:
  enable: true

#  mybatis
mybatis:
  mapper-locations: classpath:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    aggressive-lazy-loading: false
    lazy-loading-enabled: true
    #开启下划线转驼峰
    map-underscore-to-camel-case: true

#  log
logging:
  level:
    root: INFO
    org.mybatis: DEBUG

# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql

集成swagger,同样需要写一个配置类SwaggerConfig

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.List;

import static com.google.common.collect.Lists.newArrayList;

/**
 * <p>Swagger的初始化配置</p>
 *
 * @Author bob
 * @Date 2020/9/21 12:51
 */
@EnableSwagger2
@Configuration
public class SwaggerConfig {
   
   

    @Value("${swagger.enable}")
    private boolean enableSwagger;

    /**
     * 创建API应用
     * apiInfo() 增加API相关信息
     * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
     * 本例采用指定扫描的包路径来定义指定要建立API的目录。
     * @return
     */
    @Bean
    public Docket createRestApi() {
   
   
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(enableSwagger)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.test.controller"))
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    /**
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     * 访问地址:http://项目实际地址/swagger-ui.html
     * @return
     */
    private ApiInfo apiInfo() {
   
   
        return new ApiInfoBuilder()
                .title("测试 RESTful APIs")
                .description("测试 RESTful APIs")
                .termsOfServiceUrl("")
                //.license("证书")
                //.licenseUrl("证书地址")
                .version("1.0")
                .build();
    }

    private List<ApiKey> securitySchemes() {
   
   
        return newArrayList(
                new ApiKey("Authorization","Authorization","header"));
    }

    private List<SecurityContext> securityContexts() {
   
   
        return newArrayList(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .forPaths(PathSelectors.any())
                        .build()
        );
    }

    List<SecurityReference> defaultAuth() {
   
   
        AuthorizationScope authorizationScope = new AuthorizationScope("global","accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return newArrayList(
                new SecurityReference("Authorization",authorizationScopes));
    }
}

启动类

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * <p>系统管理</p>
 *
 * @Author bob
 * @Date 2020/9/18 11:39
 */
@MapperScan(value = "com.test.dao")
@EnableFeignClients
@SpringCloudApplication
public class SystemApplication {
   
   
    public static void main(String[] args) {
   
   
        SpringApplication.run(SystemApplication.class, args);
        System.out.println("系统管理服务启动成功");
    }
}

三、gateway-service

pom.xml中导入相关jar包

<dependencies>
    <!-- SpringCloud Ailibaba Nacos -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!-- SpringCloud Ailibaba Nacos Config -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

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

    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-starter-server</artifactId>
        <version>${spring-boot-admin.version}</version>
    </dependency>

    <!-- swagger ui-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
    </dependency>

    <!-- gateway中没有swagger的业务实现,所以不需要swagger2-->
    <!--<dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
    </dependency>-->

    <!-- swagger ui增强-->
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>swagger-bootstrap-ui</artifactId>
    </dependency>

</dependencies>

配置bootstrap.yml

# Tomcat
server: 
  port: 8082

# Spring
spring:
  profiles:
    active: dev 
  application:
    # 应用名称
    name: gateway-service
  main:
    #当遇到相同名字时,是否允许覆盖注册
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 配置文件格式
        file-extension: yaml
    gateway:
      discovery:
        locator:
          enabled: true  #开启服务注册和发现的功能
      routes:
        - id: system_service_route
          uri: lb://system_service/
          predicates:
          - Path=/sys/**
          filters:
          - StripPrefix=1
          - SwaggerHeaderFilter

        - id: auth-service_route
          uri: lb://auth-service/
          predicates:
          - Path=/auth/**
          filters:
          - StripPrefix=1
          - SwaggerHeaderFilter

#  log
logging:
  level:
    root: INFO

SwaggerHandler

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.*;

import java.util.Optional;

/**
 * <p>资源放行</p>
 *
 * @Author bob
 * @Date 2020/9/23 9:14
 */
@RestController
public class SwaggerHandler {
   
   

    @Autowired(required = false)
    private SecurityConfiguration securityConfiguration;

    @Autowired(required = false)
    private UiConfiguration uiConfiguration;

    private final SwaggerResourcesProvider swaggerResources;

    @Autowired
    public SwaggerHandler(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)));
    }
}

SwaggerProvider

import lombok.AllArgsConstructor;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>提供swagger资源访问</p>
 *
 * @Author bob
 * @Date 2020/9/23 9:13
 */
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {
   
   
    public static final String API_URI = "/v2/api-docs";
    private final RouteLocator routeLocator;
    private final GatewayProperties gatewayProperties;

    @Override
    public List<SwaggerResource> get() {
   
   
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        //取出gateway的route
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        //结合配置的route-路径(Path),和route过滤,只获取有效的route节点
        gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                        .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
                                predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
                                        .replace("/**", API_URI)))));
        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location) {
   
   
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }

}

SwaggerHeaderFilter这个就是配置在gateway的路由过滤器

import com.ilas.common.utils.StringUtils;
import com.ilas.gateway.config.SwaggerProvider;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

/**
 * <p>Swagger过滤器</p>
 *
 * @Author bob
 * @Date 2020/9/23 9:15
 */
@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
   
   
    /**
    * 这里注意,网上有些案例写的是这个 X-Forwarded-Prefix 会导致一些问题。
    * swagger在调用后台api的时候,会在baseUrl的ip后面加一个逗号,导致无法正常访问。
    * 所以我修改成X-Forwarded-For则正常。
    * 实际上把整个调用代码`.header(HEADER_NAME, basePath)`注释掉也能正常访问。
    */
    private static final String HEADER_NAME = "X-Forwarded-For";


    @Override
    public GatewayFilter apply(Object config) {
   
   
        return (exchange, chain) -> {
   
   
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();
            if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
   
   
                return chain.filter(exchange);
            }
            String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
            ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExchange);
        };
    }
}

SecurityConfig

import com.ilas.gateway.handler.CustomHttpBasicServerAuthenticationEntryPoint;
import com.ilas.gateway.handler.AuthenticationFailHandler;
import com.ilas.gateway.handler.AuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;

@EnableWebFluxSecurity
public class SecurityConfig {
   
   

    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    private AuthenticationFailHandler authenticationFailHandler;
    @Autowired
    private CustomHttpBasicServerAuthenticationEntryPoint customHttpBasicServerAuthenticationEntryPoint;*/

    //security的鉴权排除列表

    private static final String[] excludedAuthPages = {
   
   
            "/auth/login",
            "/doc.html",
            "/webjars/**",
            "/v2/api-docs",
            "/sys/v2/api-docs",//这个和下面两个要加上,否则无法访问后台api
            "/auth/v2/api-docs",
            "/swagger-resources/configuration/ui",
            "/swagger-resources",
            "/swagger-resources/configuration/security",
            "/swagger-ui.html"
    };

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception {
   
   
        http
                .authorizeExchange()
                .pathMatchers(excludedAuthPages).permitAll()  //无需进行权限过滤的请求路径
                .pathMatchers(HttpMethod.OPTIONS).permitAll() //option 请求默认放行
                .anyExchange().authenticated()
                .and()
                .httpBasic()
                .and()
                //此处loginPage的uri一定要与登录处理逻辑区分开,我这使用的是前后端分离,直接注释了否则访问/swagger-ui.html的时候会一直弹出登陆窗口
                /*.formLogin().loginPage("/auth/login")*/
                .authenticationSuccessHandler(authenticationSuccessHandler) //自定义认证成功处理类
                .authenticationFailureHandler(authenticationFailHandler) //自定义登陆验证失败处理类
                .and()
                .exceptionHandling().authenticationEntryPoint(customHttpBasicServerAuthenticationEntryPoint)  //自定义基于http的接口请求鉴权失败
                .and().csrf().disable()//必须支持跨域
                .logout().disable();

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
   
   
        return  NoOpPasswordEncoder.getInstance(); //默认,已经不推荐使用了,只做测试
    }

}

启动类

import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * <p>网关服务</p>
 *
 * @Author bob
 * @Date 2020/9/21 16:26
 */
@EnableAdminServer
@SpringBootApplication(exclude = {
   
   DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
public class GatewayApplication {
   
   
    public static void main(String[] args) {
   
   
        SpringApplication.run(GatewayApplication.class, args);
        System.out.println("网关服务启动成功");
    }
}

以上是从项目中摘录的,大概思路就是这样。
项目启动完,访问:http://127.0.0.1:8082/swagger-ui.html
image.png

访问http://127.0.0.1::8082/doc.html
image.png

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
安全 Java
springboot 项目 控制台一直输出/null/swagger-resources/configuration/security 解决
springboot 项目 控制台一直输出/null/swagger-resources/configuration/security 解决
364 0
|
Java API Maven
如何在gateway网关中聚合swagger
如何在gateway网关中聚合swagger
727 0
如何在gateway网关中聚合swagger
|
Java 应用服务中间件 Linux
|
20天前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
5天前
|
Java 开发者 Spring
Spring Cloud Gateway 中,过滤器的分类有哪些?
Spring Cloud Gateway 中,过滤器的分类有哪些?
13 3
|
7天前
|
负载均衡 Java 网络架构
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
20 5
|
1月前
|
安全 Java 开发者
强大!Spring Cloud Gateway新特性及高级开发技巧
在微服务架构日益盛行的今天,网关作为微服务架构中的关键组件,承担着路由、安全、监控、限流等多重职责。Spring Cloud Gateway作为新一代的微服务网关,凭借其基于Spring Framework 5、Project Reactor和Spring Boot 2.0的强大技术栈,正逐步成为业界的主流选择。本文将深入探讨Spring Cloud Gateway的新特性及高级开发技巧,助力开发者更好地掌握这一强大的网关工具。
109 6
|
3月前
|
负载均衡 Java Spring
Spring cloud gateway 如何在路由时进行负载均衡
Spring cloud gateway 如何在路由时进行负载均衡
321 15
|
3月前
|
Java Spring
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
68 3
|
3月前
|
Java 微服务 Spring
SpringCloud gateway自定义请求的 httpClient
SpringCloud gateway自定义请求的 httpClient
131 3