1.概述
Swagger用户界面允许我们查看有关REST服务的信息。这对于开发可能非常方便。但是,由于安全方面的考虑,我们可能不想在我们的公共环境中允许这种行为。
在这个简短的教程中,我们将研究如何**在生产中关闭Swagger** 。
2.昂首阔步的配置
为了用Spring设置Swagger,我们在配置bean中定义它。
让我们创建一个SwaggerConfig
类:
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("com.baeldung"))
.paths(PathSelectors.regex("/.*"))
.build();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
默认情况下,此配置bean总是注入到我们的Spring上下文中。因此,Swagger可用于所有环境。
要在生产中禁用Swagger,让我们切换是否注入了此配置bean。
3.使用Spring Profiles
在Spring中,我们可以使用@Profile
批注来启用或禁用bean的注入。
让我们尝试使用SpEL表达式来匹配“swagger”
配置文件,而不是“prod”
配置文件:
@Profile({"!prod && swagger"})
这迫使我们对要激活Swagger的环境明确。它还有助于防止在生产中意外打开它。
我们可以将注释添加到我们的配置中:
@Configuration
@Profile({"!prod && swagger"})
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
...
}
spring.profiles.active
属性的不同设置启动我们的应用程序,以测试它是否有效:
-Dspring.profiles.active=prod // Swagger is disabled
-Dspring.profiles.active=prod,anyOther // Swagger is disabled
-Dspring.profiles.active=swagger // Swagger is enabled
-Dspring.profiles.active=swagger,anyOtherNotProd // Swagger is enabled
none // Swagger is disabled
4.使用条件
Spring Profiles可能过于粗糙,无法解决功能切换问题。这种方法可能会导致配置错误以及配置文件列表冗长且无法管理的情况。
作为替代方案,我们可以使用@ConditionalOnExpression
,它允许指定用于启用bean的自定义属性:
@Configuration
@ConditionalOnExpression(value = "${useSwagger:false}")
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
...
}
如果useSwagger
”属性,则此处的默认值为false
。
为了测试这一点,我们可以在application.properties
(或application.yaml
)文件中设置属性,或将其设置为VM选项:
-DuseSwagger=true
我们应该注意,此示例不包含任何保证生产实例不会意外将useSwagger
设置为true
。
5.避免陷阱
如果启用Swagger是出于安全考虑,那么我们需要选择一种防错但易于使用的策略。
@Profile
时,某些SpEL表达式可能会违反这些目标:
@Profile({"!prod"}) // Leaves Swagger enabled by default with no way to disable it in other profiles
@Profile({"swagger"}) // Allows activating Swagger in prod as well
@Profile({"!prod", "swagger"}) // Equivalent to {"!prod || swagger"} so it's worse than {"!prod"} as it provides a way to activate Swagger in prod too
这就是我们的@Profile
示例使用以下代码的原因:
@Profile({"!prod && swagger"})
该解决方案可能是最严格的,因为它默认使Swagger处于禁用状态,并保证**不能在****“prod”** .
六,结论
在本文中,我们研究了在生产中**禁用Swagger的解决方案。**
我们研究了如何通过@Profile
和@ConditionalOnExpression
批注切换打开Swagger的bean。我们还考虑了如何防止配置错误和不希望的违约。
与往常一样,本文的示例代码可在GitHub上找到。
0 评论