问题描述
knife4j是目前比较主流的自动API文档生成工具,在生产环境使用的过程中,我们一般会屏蔽或者去除Swagger的文档口径,防止接口信息泄露,保证系统安全。
但是最近在开发过程中使用knife4j-spring-boot-starter 3.0.2过程中,发现根据官网说明配置后,还是有部分Swagger的文档口径无法完全屏蔽。
项目背景:spring-boot-starter-parent 2.2.6.RELEASE + knife4j-spring-boot-starter 3.0.2
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
属性配置:
# knife4j的增强配置
knife4j.enable=true
# 开启生产环境屏蔽,一定要先开启knife4j增强才会生效
knife4j.production=true
访问http://localhost:8080/doc.html,资源已被屏蔽:
访问/v2/api-docs
地址,资源已经被屏蔽:
访问/v3/api-docs
地址,资源未屏蔽:
问题小结:
在使用knife4j-spring-boot-starter 3.0.2 + openApi3.0
时,通过配置knife4j.enable=true和knife4j.production=true
属性,虽然屏蔽了部分Swagger的文档口径,但/v3/api-docs
口径并没有被屏蔽,还是有接口信息泄露的风险。
原因分析:
官方文档:knife4j访问权限控制-生产环境屏蔽资源
首先通过查看官方文档,我们发现在需要屏蔽的资源中确实没有包含/v3/api-docs
口径。
继续通过源码分析,在Knife4jAutoConfiguration类中,knife4j.production=true
控制是否实例化ProductionSecurityFilter对象:
@Bean
@ConditionalOnMissingBean({ProductionSecurityFilter.class})
@ConditionalOnProperty(
name = {"knife4j.production"},
havingValue = "true"
)
public ProductionSecurityFilter productionSecurityFilter(Knife4jProperties knife4jProperties) {
boolean prod = false;
ProductionSecurityFilter p = null;
if (knife4jProperties == null) {
if (this.environment != null) {
String prodStr = this.environment.getProperty("knife4j.production");
if (this.logger.isDebugEnabled()) {
this.logger.debug("swagger.production:{}", prodStr);
}
prod = Boolean.valueOf(prodStr);
}
p = new ProductionSecurityFilter(prod);
} else {
p = new ProductionSecurityFilter(knife4jProperties.isProduction());
}
return p;
}
而ProductionSecurityFilter继承自BasicFilter:
public class BasicFilter {
private Logger logger = LoggerFactory.getLogger(BasicFilter.class);
protected List<Pattern> urlFilters = null;
//需要屏蔽的资源
public BasicFilter() {
this.urlFilters = new ArrayList();
this.urlFilters.add(Pattern.compile(".*?/doc\\.html.*", 2));
this.urlFilters.add(Pattern.compile(".*?/v2/api-docs.*", 2));
this.urlFilters.add(Pattern.compile(".*?/v2/api-docs-ext.*", 2));
this.urlFilters.add(Pattern.compile(".*?/swagger-resources.*", 2));
this.urlFilters.add(Pattern.compile(".*?/swagger-ui\\.html.*", 2));
this.urlFilters.add(Pattern.compile(".*?/swagger-resources/configuration/ui.*", 2));
this.urlFilters.add(Pattern.compile(".*?/swagger-resources/configuration/security.*", 2));
}
//路径匹配
protected boolean match(String uri) {
boolean match = false;
if (uri != null) {
Iterator var3 = this.getUrlFilters().iterator();
while(var3.hasNext()) {
Pattern pattern = (Pattern)var3.next();
if (pattern.matcher(uri).matches()) {
match = true;
break;
}
}
}
return match;
}
可以发现在knife4j-spring-boot-starter 3.0.2 版本中,BasicFilter屏蔽的资源中并不包括/v3/api-docs
资源口径,这也就导致knife4j.production=true属性不能屏蔽/v3/api-docs
资源口径。
解决方案:
方式一:自定义ProductionSecurityFilter
上文我们已经分析出没有屏蔽/v3/api-docs
资源口径的原因是ProductionSecurityFilter对象的父类BasicFilter屏蔽的资源列表中缺少/v3/api-docs
资源口径,首先想到的是是否能通过自定义ProductionSecurityFilter对象来手动添加/v3/api-docs
资源口径,实现资源屏蔽。
在项目的Knife4j的配置类Knife4jConfig中添加如下代码:
@Bean
@ConditionalOnProperty(
name = {"knife4j.production"},
havingValue = "true"
)
public ProductionSecurityFilter productionSecurityFilter(Knife4jProperties knife4jProperties) {
boolean prod = false;
ProductionSecurityFilter p = null;
if (knife4jProperties == null) {
if (this.environment != null) {
String prodStr = this.environment.getProperty("knife4j.production");
log.debug("swagger.production:{}", prodStr);
prod = Boolean.valueOf(prodStr);
}
p = new MyProductionSecurityFilter(prod);
} else {
p = new MyProductionSecurityFilter(knife4jProperties.isProduction());
}
return p;
}
//自定义ProductionSecurityFilter,添加`/v3/api-docs`资源口径
public static class MyProductionSecurityFilter extends ProductionSecurityFilter{
public MyProductionSecurityFilter(boolean production) {
super(production);
super.urlFilters.add(Pattern.compile(".*?/v3/api-docs.*", 2));
}
}
方式二:升级knife4j版本到3.0.3
将knife4j-spring-boot-starter升级到最新的版本3.0.3
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
该版本中BasicFilter屏蔽资源列表中已经包含/v3/api-docs
资源口径:
方式三:禁用springfox自动配置
因为knife4j底层是依赖的springfox,也可以通过禁用springfox来屏蔽资源。
属性配置:文章来源:https://www.toymoban.com/news/detail-732209.html
#禁用springfox
springfox.documentation.enabled=false
# 如果禁用springfox,则不能开启knife4j增强,否则项目启动会报错
knife4j.enable=false
文章来源地址https://www.toymoban.com/news/detail-732209.html
到了这里,关于knife4j生产环境资源屏蔽的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!