Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding authorization to Annotation-driven swagger.json with Jersey 2 and Spring Boot

I'm trying to add Basic Authentication to Swagger UI for a to a Swagger-annotated Jersey 2.0 web service built with Spring Boot. I'm using:

  • Spring Boot 1.5.4
  • spring-boot-starter-jersey
  • Swagger UI 3.0.4
  • (Maven package) swagger-jersey2-jaxrs 1.5.13

I'm able to generate a swagger.json file with the following JerseyConfig and with Swagger annotations on my Resources. This article was immensely helpful in getting this far.

@Component
public class JerseyConfiguration extends ResourceConfig {
  private static Log logger = LogFactory.getLog(JerseyConfiguration.class);

  @Value("${spring.jersey.application-path:/}")
  private String apiPath;

  public JerseyConfiguration() {
    registerEndpoints();
    configureSwagger();
  }

  private void registerEndpoints() {
    register(MyEndpoints.class);

    // Generate Jersey WADL at /<Jersey's servlet path>/application.wadl
    register(WadlResource.class);

    // Lets us get to static content like swagger
    property(ServletProperties.FILTER_STATIC_CONTENT_REGEX, "((/swagger/.*)|(.*\\.html))");
   }


  /**
   * Configure the Swagger documentation for this API.
   */
  private void configureSwagger() {
    // Creates file at localhost:port/swagger.json
    this.register(ApiListingResource.class);
    this.register(SwaggerSerializers.class);


    BeanConfig config = new BeanConfig();
    config.setConfigId("example-jersey-app");
    config.setTitle("Spring Boot + Jersey + Swagger");
    config.setVersion("2");
    config.setContact("Me <[email protected]>");
    config.setSchemes(new String[] {"http", "https"});
    config.setResourcePackage("com.example.api");
    config.setBasePath(this.apiPath);
    config.setPrettyPrint(true);
    config.setScan(true);
  }
}

Now I want to be able to use Basic Authentication to connect to these services from Swagger UI. I've configured it in Spring and can use it to authenticate to the site, but not from Swagger UI. Unfortunately, none of the Spring Boot examples currently on the Swagger sample site include Jersey and authentication, and none of the Jersey examples use Spring Boot and @SpringBootApplication like I'm using on in my project.

How do I get Basic Auth to show up in the Swagger UI?

like image 478
k-den Avatar asked Apr 27 '17 07:04

k-den


1 Answers

I was able to get this to work by adding ServletConfigAware to JerseyConfiguration. Then I could use the same style of Swagger configuration used in the Swagger Bootstrap.java examples.

@Component
public class JerseyConfiguration extends ResourceConfig  implements ServletConfigAware{
  private ServletConfig servletConfig;

// ... this is all unchanged ...

  /**
   * Configure the Swagger documentation for this API.
   */
  private void configureSwagger() {
    // Creates file at localhost:port/swagger.json
    this.register(ApiListingResource.class);
    this.register(SwaggerSerializers.class);


    BeanConfig config = new BeanConfig();

// ... this is all unchanged ...

    config.setScan(true);

    Swagger swagger = new Swagger();
    swagger.securityDefinition("basicAuth", new BasicAuthDefinition());
    new SwaggerContextService().withServletConfig(servletConfig).updateSwagger(swagger);

  }

  @Override
  public void setServletConfig(ServletConfig servletConfig) {
    logger.info("Setting ServletConfig");
    this.servletConfig = servletConfig;
  }
}

After making these changes, and adding annotations like the following to my endpoints:

@Api(value = "/api", description = "My super API",
authorizations = {@Authorization(value="basicAuth")})
@Path("api")
@Component
public class MyApi {

I saw the following changes:

Added to my swagger.json:

"securityDefinitions":{"basicAuth":{"type":"basic"}}
...
"security":[{"basicAuth":[]}]}}

Also, in Swagger UI, a new green button appeared in the same row as the Schemes dropdown, that says "Authorize" with an open lock on it. If I click on it, a popup shows up where I can enter the username and password. Now those credentials are sent to the API when I use the Swagger UI "Try It" feature.

like image 157
k-den Avatar answered Dec 31 '22 18:12

k-den