18

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

Athomas
  • 533
  • 1
  • 6
  • 19
  • Pretty much nothing. I am totally new to Swagger. I was trying to see if setting jacksonScalaSupport.setRegisterScalaModule(false) in SwaggerConfig would work – Athomas Dec 12 '14 at 11:35

3 Answers3

44

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.*");
}
Dilip Krishnan
  • 5,417
  • 3
  • 37
  • 53
  • Hi Dilip, Thanks for the response. I had a work around by using an environment specific flag. Only if the flag is true I call the initiallize() method in my custom SwaggerSpringMvcPlugin. – Athomas Jan 17 '15 at 05:11
  • Unfortunately this does not work for me with Spring 1.4.1 and Swagger 2.6.1, the error occurs before the configuration methods are called. – Uncle Long Hair Feb 11 '17 at 20:35
  • `@Profile` doesn't appear to work on `@Bean` methods. According to the [spring docs](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html) "Any `@Component` or `@Configuration` can be marked with `@Profile`..." – peterl May 04 '17 at 02:22
  • 3
    /swagger-ui.html still available but there is no methods. Is there way to forbid URL ? – gstackoverflow Sep 28 '17 at 09:18
  • Is there anyway to disable the security in Swagger ? – Stephane Dec 11 '18 at 11:02
  • What I did is set the scope of springfox-swagger-ui as provided in pom. Then on the production environment, it won't find this jar. So the swagger-ui.html is totally disabled. – Xmagic Mar 11 '19 at 09:47
3

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;
    }
}
Custard
  • 766
  • 1
  • 7
  • 15
  • 1
    This could be more easily implemented by using Spring Security instead of coding your own authentication approach? – Kevin Hooke Aug 11 '17 at 20:08
-3

You try this way

@Configuration
@EnableSwagger
// Loads the spring beans required by the framework
public class MySwaggerConfig
{

    private SpringSwaggerConfig springSwaggerConfig;

    /**
     * Required to autowire SpringSwaggerConfig
     */
    @Autowired
    public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig)
    {
        this.springSwaggerConfig = springSwaggerConfig;
    }

    /**
     * Every SwaggerSpringMvcPlugin bean is picked up by the swagger-mvc
     * framework - allowing for multiple swagger groups i.e. same code base
     * multiple swagger resource listings.
     */
    @Bean
    public SwaggerSpringMvcPlugin customImplementation()
    {
        return new SwaggerSpringMvcPlugin(this.springSwaggerConfig).apiInfo(apiInfo()).includePatterns(
                ".*?");
    }

    private ApiInfo apiInfo()
    {
        ApiInfo apiInfo = new ApiInfo(
                "xx", 
                "xxxx",
                "My Apps API terms of service", 
                "xxx",
                null,
                null);
        return apiInfo;
    }
}

pom is swagger-springmvc. veriosn is 0.9.5,

start server after request http://localhost:8080/appName/api-docs

jack
  • 113
  • 2
  • 9