Swagger is a canonical and complete framework for generating, describing, invoking, and visualizing RESTful Web services.

After SpringBoot integrates Swagger, add corresponding annotations to the Controller layer to generate interface documents, which are widely used in front-end and back-end projects.

Unified authentication

In a specific project, most of the resources are protected (see: Spring Boot elegant integration with Spring Security), so how to set the global login Token on the Swagger page? Swagger provides the abstract SecurityScheme class to solve the authentication problem. There are three implementations of Swagger:

  • ApiKey: Supports header and Query authentication.
  • BasicAuth: Simple authentication;
  • OAuth: oAuth2-based authentication.

Today we will focus on the ApiKey header authentication, which is to add login certificate Token to all the headers requested on Swagger page.

Integrates with starter provided by the Spring4All community

<! -- swagger2 -->
<dependency>
  <groupId>com.spring4all</groupId>
  <artifactId>swagger-spring-boot-starter</artifactId>
  <version>1.9.1. RELEASE</version>
</dependency>
Copy the code

Configure in the configuration file:

# swagger configuration
swagger:
  # Enable swagger
  enabled: true
  title: Gits_ Interface documentation
  Configure unified global authentication
  authorization:
    key-name: GitsSessionID
Copy the code

Add token with key GitsSessionID in request header, start project, access IP :port/ swagger-uI.html

Add SpringSecurity login interface to Swagger page

There are some scenarios where we need to manually add interfaces to Swagger, such as non-SpringMVC annotation exposed interfaces (defined in filter) that cannot be annotated to generate API interface documentation.

The user name and password login interface of SpringSecurity is intercepted in filter. You can review the previous article: SpringSecurity password login source analysis (with flow chart).

Therefore, the login interface cannot be seen in Swagger, which is very inconvenient in normal development and testing. We need to access the login interface in postman tool to obtain the Token, and then go back to Swagger page to set the Token. As a straight iron man, I want to complete this operation only in Swagger page. What should I do?

You can manually add interfaces to Swagger files by implementing the ApiListingScannerPlugin provided by Swagger.

Add SpringSecurity login interface to Swagger

/** * Add swagger interface manually@author songyinyin
 * @date 2020/6/17 δΈ‹εˆ 10:03
 */
@Component
public class SwaggerAddtion implements ApiListingScannerPlugin {
    Implement this method to manually add ApiDescriptions **@param context - Documentation context that can be used infer documentation context
     * @return List of {@link ApiDescription}
     * @see ApiDescription
     */
    @Override
    public List<ApiDescription> apply(DocumentationContext context) {
        Operation usernamePasswordOperation = new OperationBuilder(new CachingOperationNameGenerator())
            .method(HttpMethod.POST)
            .summary("Username and password login")
            .notes("The username/password login")
            .consumes(Sets.newHashSet(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) // Receive parameter format
            .produces(Sets.newHashSet(MediaType.APPLICATION_JSON_VALUE)) // Returns the parameter format
            .tags(Sets.newHashSet("Login"))
            .parameters(Arrays.asList(
                new ParameterBuilder()
                    .description("Username")
                    .type(new TypeResolver().resolve(String.class))
                    .name("username")
                    .defaultValue("admin")
                    .parameterType("query")
                    .parameterAccess("access")
                    .required(true)
                    .modelRef(new ModelRef("string"))
                    .build(),
                new ParameterBuilder()
                    .description("Password")
                    .type(new TypeResolver().resolve(String.class))
                    .name("password")
                    .defaultValue("123456")
                    .parameterType("query")
                    .parameterAccess("access")
                    .required(true)
                    .modelRef(new ModelRef("string"))
                    .build(),
                new ParameterBuilder()
                    .description("Unique identification of verification code")
                    .type(new TypeResolver().resolve(String.class))
                    .name("randomKey")
                    .defaultValue("666666")
                    .parameterType("query")
                    .parameterAccess("access")
                    .required(true)
                    .modelRef(new ModelRef("string"))
                    .build(),
                new ParameterBuilder()
                    .description("Verification code")
                    .type(new TypeResolver().resolve(String.class))
                    .name("code")
                    .parameterType("query")
                    .parameterAccess("access")
                    .required(true)
                    .modelRef(new ModelRef("string"))
                    .build()
            ))
            .responseMessages(Collections.singleton(
                new ResponseMessageBuilder().code(200).message("Request successful")
                    .responseModel(new ModelRef(
                        "xyz.gits.boot.common.core.response.RestResponse")
                    ).build()))
            .build();

        ApiDescription loginApiDescription = new ApiDescription("login"."/login"."Login interface",
            Arrays.asList(usernamePasswordOperation), false);

        return Arrays.asList(loginApiDescription);
    }

    /** * Whether to use this plug-in **@paramDocumentationType Swagger Document type *@returnTrue to enable * /
    @Override
    public boolean supports(DocumentationType documentationType) {
        returnDocumentationType.SWAGGER_2.equals(documentationType); }}Copy the code

The code is a little long, so explain it a little bit. The Supports method specifies whether to use this plug-in or not. The Apply method can manually add an ApiDescription and its return value is a collection of ApiDescription that can be constructed using the builder pattern. First construct a user name password login Operation, which specifies the request method (tags), parameters (parameters), responseMessages, etc. With build good usernamePasswordOperation finally, the path of the request, and request instructions, such as tectonic ApiDescription return should be carried out.

You’ll see the interface you just defined on the Swagger page.

Results show

  1. Obtaining verification code

  1. Logging In to obtain a Token

  1. Swagger unified certification

  1. Access protected resources


Good man wait slowly, the original is not easy, dot a praise and then go. Concern public number can white piao 😘, do not next time certain, this 🀣