1. Обзор
Пользовательский интерфейс Swagger позволяет нам просматривать информацию о наших службах REST. Это может быть очень удобно для разработки. Однако из соображений безопасности мы можем не разрешить такое поведение в общедоступных средах.
В этом коротком уроке мы рассмотрим, как отключить Swagger в рабочей среде .
2. Конфигурация чванства
Чтобы настроить 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.foreach"))
.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
, что позволяет указать пользовательские свойства для включения компонента:
@Configuration
@ConditionalOnExpression(value = "${useSwagger:false}")
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
...
}
Если свойство « useSwagger
» отсутствует, значением по умолчанию здесь является false
.
Чтобы проверить это, мы можем либо установить свойство в файле application.properties
(или application.yaml
), либо установить его как параметр виртуальной машины:
-DuseSwagger=true
Следует отметить, что этот пример не включает никаких гарантий того, что наш производственный экземпляр не может случайно установить для useSwagger значение
true
.
5. Избегайте ловушек
Если включение Swagger является проблемой безопасности, нам нужно выбрать стратегию, которая защитит от ошибок, но проста в использовании.
Некоторые выражения SpEL могут работать против этих целей, когда мы используем @Profile
:
@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» .
6. Заключение
В этой статье мы рассмотрели решения по отключению Swagger в продакшене.
Мы рассмотрели, как переключить bean-компонент, который включает Swagger, с помощью аннотаций @Profile
и @ConditionalOnExpression
. Мы также рассмотрели, как защититься от неправильной настройки и нежелательных значений по умолчанию.
Как всегда, пример кода из этой статьи можно найти на GitHub .