Перейти к основному содержимому

Как отключить Swagger-ui в продакшене

· 3 мин. чтения

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 .