如何在生產中關閉Swagger-ui
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上找到。