How to Turn Off Swagger-ui in Production – 如何在生产中关闭Swagger-ui

最后修改: 2020年 8月 24日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

The Swagger user interface allows us to view information about our REST services. This can be very convenient for development. However, owing to security concerns, we might not want to allow this behavior in our public environments.

Swagger用户界面允许我们查看关于REST服务的信息。这对于开发来说是非常方便的。然而,出于安全考虑,我们可能不希望在公共环境中允许这种行为。

In this short tutorial, we’ll look at how to turn Swagger off in production.

在这个简短的教程中,我们将看看如何在生产中关闭Swagger

2. Swagger Configuration

2.Swagger配置

To set up Swagger with Spring, we define it in a configuration bean.

为了用Spring设置Swagger,我们在一个配置bean中定义它。

Let’s create a SwaggerConfig class:

让我们创建一个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/");
    }
}

By default, this configuration bean is always injected into our Spring context. Thus, Swagger becomes available for all environments.

默认情况下,这个配置Bean总是被注入到我们的Spring上下文中。因此,Swagger对所有环境都可用。

To disable Swagger in production, let’s toggle whether this configuration bean is injected.

为了在生产中禁用Swagger,让我们切换这个配置Bean是否被注入。

3. Using Spring Profiles

3.使用Spring Profiles

In Spring, we can use the @Profile annotation to enable or disable the injection of beans.

在Spring中,我们可以使用@Profile注解来启用或禁用bean的注入。

Let’s try using a SpEL expression to match the “swagger” profile, but not the “prod” profile:

让我们尝试使用SpEL表达式来匹配“swagger”配置文件,但不匹配“prod”配置文件。

@Profile({"!prod && swagger"})

This forces us to be explicit about environments where we want to activate Swagger. It also helps to prevent accidentally turning it on in production.

这迫使我们明确说明我们想要激活Swagger的环境。这也有助于防止在生产中意外地打开它。

We can add the annotation to our configuration:

我们可以将注解添加到我们的配置中。

@Configuration 
@Profile({"!prod && swagger"})
@EnableSwagger2 
public class SwaggerConfig implements WebMvcConfigurer {
    ...
}

Now, let’s test that it works, by launching our application with different settings for the spring.profiles.active property:

现在,让我们通过启动我们的应用程序并对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. Using Conditionals

4.使用条件语句

Spring Profiles can be too coarse-grained a solution for feature toggles. This approach can lead to configuration errors and lengthy, unmanageable lists of profiles.

对于功能切换,Spring Profiles可能是一种过于粗略的解决方案。这种方法可能会导致配置错误和冗长的、无法管理的配置文件列表。

As an alternative, we can use @ConditionalOnExpression, which allows specifying custom properties for enabling a bean:

作为替代,我们可以使用@ConditionalOnExpression,它允许为启用Bean指定自定义属性。

@Configuration
@ConditionalOnExpression(value = "${useSwagger:false}")
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
    ...
}

If the “useSwagger” property is missing, the default here is false.

如果”useSwagger“属性缺失,这里默认为false

To test this, we can either set the property in the application.properties (or application.yaml) file, or set it as a VM option:

为了测试这一点,我们可以在application.properties(或application.yaml)文件中设置该属性,或者将其设置为VM选项。

-DuseSwagger=true

We should note that this example does not include any way of guaranteeing that our production instance cannot accidentally have useSwagger set to true.

我们应该注意,这个例子不包括任何保证我们的生产实例不会意外地将useSwagger设置为true的方法。

5. Avoiding Pitfalls

5.避免陷阱

If enabling Swagger is a security concern, then we need to choose a strategy that’s mistake-proof, but easy to use.

如果启用Swagger是出于安全考虑,那么我们需要选择一个既能防止错误,又能方便使用的策略。

Some SpEL expressions can work against these aims when we use @Profile:

当我们使用@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

This is why our @Profile example used:

这就是为什么我们的@Profile例子使用。

@Profile({"!prod && swagger"})

This solution is probably the most rigorous, as it makes Swagger disabled by default and guarantees it cannot be enabled in “prod”

这个解决方案可能是最严格的,因为它使Swagger 默认禁用,并保证它在“prod”中不能被启用。

6. Conclusion

6.结语

In this article, we looked at solutions for disabling Swagger in production.

在这篇文章中,我们探讨了在生产中禁用Swagger的解决方案

We looked at how to toggle the bean that turns Swagger on, via the @Profile and @ConditionalOnExpression annotations. We also considered how to protect against misconfiguration and undesirable defaults.

我们研究了如何通过@Profile@ConditionalOnExpression注解来切换开启Swagger的bean。我们还考虑了如何防止错误的配置和不受欢迎的默认值。

As always, the example code from this article can be found over on GitHub.

一如既往,本文中的示例代码可以在GitHub上找到over