«1. Обзор
Пользовательский интерфейс Swagger позволяет нам просматривать информацию о наших службах REST. Это может быть очень удобно для разработки. Однако из соображений безопасности мы можем не разрешить такое поведение в общедоступных средах.
В этом коротком руководстве мы рассмотрим, как отключить Swagger в рабочей среде.
2. Конфигурация Swagger
Чтобы настроить Swagger с помощью Spring, мы определяем его в 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/");
}
}
По умолчанию этот компонент конфигурации всегда внедряется в наш контекст Spring. Таким образом, Swagger становится доступным для всех сред.
Чтобы отключить Swagger в производственной среде, давайте переключим, будет ли внедряться этот компонент конфигурации.
3. Использование профилей Spring
В 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), либо установить его как параметр виртуальной машины:
-DuseSwagger=true
Следует отметить, что в этом примере не включать какой-либо способ гарантировать, что наш производственный экземпляр не может случайно установить для useSwagger значение true.
5. Как избежать ловушек
Если включение Swagger является проблемой безопасности, нам нужно выбрать стратегию, которая защитит от ошибок, но проста в использовании.
@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
Некоторые выражения SpEL могут работать против этих целей, когда мы используем @Profile:
@Profile({"!prod && swagger"})
Вот почему используется наш пример @Profile:
Это решение вероятно, самый строгий, поскольку он отключает Swagger по умолчанию и гарантирует, что его нельзя будет включить в «prod».
6. Заключение
В этой статье мы рассмотрели решения по отключению Swagger в продакшене.