• springboot3.x集成SpringDoc Swagger3


    近期将springboox2.x升级到了3.x,索性将swagger2也同步升级到swagger3,具体过程如下。

    一、添加maven依赖

    1. <dependency>
    2. <groupId>org.springdocgroupId>
    3. <artifactId>springdoc-openapi-starter-webmvc-uiartifactId>
    4. <version>2.1.0version>
    5. dependency>

    二、编写SpringDoc配置类

    1. /**
    2. * spring doc配置
    3. */
    4. @Configuration
    5. public class SpringDocConfig {
    6. @Bean
    7. public OpenAPI restfulOpenAPI() {
    8. return new OpenAPI()
    9. .info(new Info().title("springboot3.x demo")
    10. .description("Spring Boot3 Restful API")
    11. .version("V1.0.0")
    12. .license(new License().name("访问SpringDoc官方网站").url("http://springdoc.org")))
    13. .externalDocs(new ExternalDocumentation()
    14. .description("欢迎访问LDY的技术博客")
    15. .url("https://blog.csdn.net/ldy1016"));
    16. }
    17. }

    启动项目,在浏览器输入{ip}:{端口}/swagger-ui/index.html,查看效果,如127.0.0.1:8080/swagger-ui/index.html

    三、添加swagger3注解

    首先来看一下swagger2和swagger3中注解的对应关系,方便使用swagger2的同学升级到swagger3

    swagger2swagger3说明
    @Api@Tag用在请求的类上,表示对类的说明
    @ApiIgnore@Hidden隐藏显示
    @ApiImplicitParam@Parameter用在请求方法上,指定具体某一个请求参数的详细信息
    @ApiImplicitParams@Parameters用在请求方法上,表示一组参数的说明
    @ApiModel@Schema用于请求或者响应类上,说明请求或者响应数据
    @ApiModelProperty@Schema用在属性上,描述响应类的属性用,swagger2中的hidden = true属性相当于swagger3中 的accessMode = READ_ONLY属性
    @ApiOperation@Operation用在请求的方法上,说明方法的用途、作用对应注解中swagger2中的value和notes属性对应swagger3中的summary和description属性
    @ApiParam@Parameter描述参数信息

     参考示例:

    @Tag 描述整个类

    1. @Tag(name = "用户管理")
    2. @RestController
    3. @RequestMapping("/user")
    4. public class UserController {}

    @Operation 用在请求的方法上,说明方法的用途、作用

    1. @Operation(summary = "查询用户列表接口",description = "部门用户信息")
    2. @GetMapping("/list")
    3. public List list(@RequestBody UserQueryParam param) {
    4. //TODO 查询用户信息并返回
    5. return null;
    6. }

    @Schema 用于请求或者响应类上,说明请求或者响应数据,用在属性上,描述响应类的属性用

    1. @Data
    2. @Schema(title = "用户信息查询参数")
    3. public class UserQueryParam implements Serializable {
    4. private static final long serialVersionUID = 4159622041608936674L;
    5. @Schema(title = "部门")
    6. private String department;
    7. @Schema(title = "姓名")
    8. private String name;
    9. @Schema(title = "性别",allowableValues = "0,1",example = "0")
    10. private Integer sex;
    11. }

    打开swagger页面查看效果

    四、自定义过滤器,防止swagger文档未授权访问

    swagger3未授权访问的路径主要包括/v3/api-docs/swagger-ui/index.html

    本人提供的解决方案就是通过过滤器的方式对请求进行验证,请求的时候需要在链接后面加上我们自定义的token参数,通过验证token判断是否是合法的访问,注意,添加过滤器后需要在启动类上加上@ServletComponentScan注解才能生效,具体实现如下:

    1. import jakarta.servlet.Filter;
    2. import jakarta.servlet.FilterChain;
    3. import jakarta.servlet.FilterConfig;
    4. import jakarta.servlet.ServletException;
    5. import jakarta.servlet.ServletRequest;
    6. import jakarta.servlet.ServletResponse;
    7. import jakarta.servlet.annotation.WebFilter;
    8. import jakarta.servlet.http.HttpServletRequest;
    9. import jakarta.servlet.http.HttpServletResponse;
    10. import lombok.extern.slf4j.Slf4j;
    11. /**
    12. * 解决swagger-ui 未授权访问漏洞,需要在启动类加@ServletComponentScan注解
    13. *
    14. * @author ldy
    15. * @since V1.0.0
    16. */
    17. @Slf4j
    18. @WebFilter(urlPatterns = {"/v3/api-docs",
    19. "/swagger-ui/index.html"}, filterName = "springDocFilter")
    20. public class SpringDocFilter implements Filter {
    21. /**
    22. * 访问swagger的token
    23. */
    24. @Value("${swagger.token:123@abc}")
    25. private String swaggerToken;
    26. @Override
    27. public void init(FilterConfig filterConfig) throws ServletException {
    28. Filter.super.init(filterConfig);
    29. }
    30. @Override
    31. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
    32. throws IOException, ServletException {
    33. HttpServletRequest request = (HttpServletRequest) servletRequest;
    34. HttpServletResponse response = (HttpServletResponse) servletResponse;
    35. log.info("do springDocFilter,url:{}", request.getRequestURL());
    36. // 请求来源地址
    37. String referer = request.getHeader("referer");
    38. log.info("referer is {}", referer);
    39. /**
    40. * 1、请求来源地址为空,判断token是否匹配 2、请求来源地址不为空,判断来源地址是否包含正确的token
    41. */
    42. if (StringUtils.isBlank(referer)) {
    43. // 获取token
    44. String token = request.getParameter("token");
    45. log.info("token is {}", token);
    46. // 来源地址为空,判断token是否匹配
    47. if (!StringUtils.equals(swaggerToken, token)) {
    48. log.error("禁止未授权访问,url:{}", request.getRequestURL());
    49. response.setStatus(403);
    50. servletResponse.setContentType("application/json");
    51. servletResponse.setCharacterEncoding("UTF-8");
    52. servletResponse.getWriter().write(JsonUtil.toJsonString(DJResult.error(-1, "禁止未授权访问", "")));
    53. return;
    54. }
    55. } else if (!referer.contains(swaggerToken)) {
    56. log.warn("禁止未授权访问,url:{}", request.getRequestURL());
    57. response.setStatus(403);
    58. servletResponse.setContentType("application/json");
    59. servletResponse.setCharacterEncoding("UTF-8");
    60. servletResponse.getWriter().write(JsonUtil.toJsonString(DJResult.error(-1, "禁止未授权访问", "")));
    61. return;
    62. }
    63. filterChain.doFilter(servletRequest, servletResponse);
    64. }
    65. @Override
    66. public void destroy() {
    67. Filter.super.destroy();
    68. }
    69. }

    通过添加如上所示的过滤器后,我们就可以通过在路径后面加上token参数进行访问文档地址了,如:127.0.0.1:8080/swagger-ui/index.html?token=123@abc

    没有加token参数或者token参数匹配不上的请求会直接返回“禁止未授权访问”。这里的token尽量设置复杂一点。

  • 相关阅读:
    ​复旦大学邱锡鹏组:CNN-NER——极其简单有效的嵌套命名实体识别方法
    点云从入门到精通技术详解100篇-基于深度学习的三维植物点云分割网络
    php-java-net-python-爱心公益网站()计算机毕业设计程序
    【Python 实战基础】Pandas中Series与数据list如何互相转换
    macOS 13 Ventura后,打开软件显示“XXapp已损坏,无法打开”如何解决?
    JavaWeb---HTML
    DES算法是对称算法吗,能否通过在线工具进行DES解密?
    【JVM深层系列】「逆向ClassLoader加载机制」认识一下线程上下文类加载器实现
    什么是PolarDB
    【mysql 提高查询效率】Mysql 数据库查询好慢问题解决
  • 原文地址:https://blog.csdn.net/LDY1016/article/details/136502829