Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disabling Swagger with Spring MVC

I am using Swagger with Spring MVC. I would like to selectively disable swagger in specific environments (like Production). How can I do that?

like image 294
Athomas Avatar asked Dec 12 '14 11:12

Athomas


People also ask

How do I disable Swagger API?

Using Spring Profiles In Spring, we can use the @Profile annotation to enable or disable the injection of beans. 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.

Should you disable Swagger in production?

We should not enable swagger in production due to security threats. In.net core version 6.0 version, we can protect it with the below code in Program.

Can we use Swagger in Spring MVC?

Swagger Spring MVC uses Spring MVC annotations to compute the documentation, but it also understands Swagger annotations.

Is Swagger part of spring boot?

Swagger2 is an open source project used to generate the REST API documents for RESTful web services. It provides a user interface to access our RESTful web services via the web browser. To enable the Swagger2 in Spring Boot application, you need to add the following dependencies in our build configurations file.


2 Answers

In case you're using 1.x version of springfox formerly swagger-springmvc

When you configure your swagger spring-mvc plugin you can use the enable method to which you can pass in a boolean based on environment/profile etc.

@Bean 
public SwaggerSpringMvcPlugin customImplementation(){
    return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
        .apiInfo(apiInfo())
        .enable(environmentSpeficicBooleanFlag) //<--- Flag to enable or disable possibly loaded using a property file
        .includePatterns(".*pet.*");
}

Another way to do it is using spring profiles

@Bean
@Profile("production")
public SwaggerSpringMvcPlugin customImplementation(){
    return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
        .apiInfo(apiInfo())
        .enable(false) //<--- Flag set to false in the production profile
        .includePatterns(".*pet.*");
}

In case you're using 2.x version of springfox

When you configure your swagger spring-mvc plugin you can use the enable method to which you can pass in a boolean based on environment/profile etc.

@Bean 
public Docket customImplementation(){
    return new Docket(SWAGGER_2)
        .apiInfo(apiInfo())
        .enable(environmentSpeficicBooleanFlag) //<--- Flag to enable or disable possibly loaded using a property file
        .includePatterns(".*pet.*");
}

Another way to do it is using spring profiles

@Bean
@Profile("production")
public Docket customImplementation(){
    return new Docket(SWAGGER_2)
        .apiInfo(apiInfo())
        .enable(false) //<--- Flag set to false in the production profile
        .includePatterns(".*pet.*");
}
like image 61
Dilip Krishnan Avatar answered Oct 19 '22 01:10

Dilip Krishnan


Dilip's answer is what you've asked for (I haven't tested it yet). But I have an additional scenario to deal with that may be of interest: on a public test box, I want the documentation to be enabled but private.

I've added the following to my WebMvcConfigurerAdapter which adds Basic Auth

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new SwaggerInterceptor())
            .addPathPatterns("/api-docs");
}

private class SwaggerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!authHeaderValid(request.getHeader("Authorization"))) {
            response.addHeader("Access-Control-Allow-Origin", "null");
            response.addHeader("WWW-Authenticate", "Basic realm=\"\"");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().println("HTTP Status " + HttpServletResponse.SC_UNAUTHORIZED);

            return false;
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }

    private boolean authHeaderValid(String authorization) {
        if (authorization != null && authorization.startsWith("Basic ")) {
            final String[] values = new String(Base64.getDecoder().decode(authorization.substring("Basic ".length()))).split(":");

            return values[0].equals("username") && values[1].equals("password");
        }

        return false;
    }
}
like image 33
Custard Avatar answered Oct 19 '22 01:10

Custard