content: package com.snow.common.swagger.config;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  import java.util.function.Predicate;
  import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  import org.springframework.boot.context.properties.EnableConfigurationProperties;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.context.annotation.Import;
  import springfox.documentation.builders.ApiInfoBuilder;
  import springfox.documentation.builders.PathSelectors;
  import springfox.documentation.builders.RequestHandlerSelectors;
  import springfox.documentation.service.ApiInfo;
  import springfox.documentation.service.ApiKey;
  import springfox.documentation.service.AuthorizationScope;
  import springfox.documentation.service.Contact;
  import springfox.documentation.service.SecurityReference;
  import springfox.documentation.service.SecurityScheme;
  import springfox.documentation.spi.DocumentationType;
  import springfox.documentation.spi.service.contexts.SecurityContext;
  import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
  import springfox.documentation.spring.web.plugins.Docket;
  import springfox.documentation.swagger2.annotations.EnableSwagger2;
  
  @Configuration
  @EnableSwagger2
  @EnableConfigurationProperties(SwaggerProperties.class)
  @ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
  @Import({SwaggerBeanPostProcessor.class, SwaggerWebConfiguration.class})
  public class SwaggerAutoConfiguration
  {
      /**
       * 默认的排除路径，排除Spring Boot默认的错误处理路径和端点
       */
      private static final List<String> DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");
  
      private static final String BASE_PATH = "/**";
  
      @Bean
      public Docket api(SwaggerProperties swaggerProperties)
      {
          // base-path处理
          if (swaggerProperties.getBasePath().isEmpty())
          {
              swaggerProperties.getBasePath().add(BASE_PATH);
          }
          // noinspection unchecked
          List<Predicate<String>> basePath = new ArrayList<Predicate<String>>();
          swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path)));
  
          // exclude-path处理
          if (swaggerProperties.getExcludePath().isEmpty())
          {
              swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH);
          }
  
          List<Predicate<String>> excludePath = new ArrayList<>();
          swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
  
          ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(swaggerProperties.getHost())
                  .apiInfo(apiInfo(swaggerProperties)).select()
                  .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()));
  
          swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p)));
          swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate()));
  
          return builder.build().securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping("/");
      }
  
      /**
       * 安全模式，这里指定token通过Authorization头请求头传递
       */
      private List<SecurityScheme> securitySchemes()
      {
          List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
          apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
          return apiKeyList;
      }
  
      /**
       * 安全上下文
       */
      private List<SecurityContext> securityContexts()
      {
          List<SecurityContext> securityContexts = new ArrayList<>();
          securityContexts.add(
                  SecurityContext.builder()
                          .securityReferences(defaultAuth())
                          .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
                          .build());
          return securityContexts;
      }
  
      /**
       * 默认的全局鉴权策略
       *
       * @return
       */
      private List<SecurityReference> defaultAuth()
      {
          AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
          AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
          authorizationScopes[0] = authorizationScope;
          List<SecurityReference> securityReferences = new ArrayList<>();
          securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
          return securityReferences;
      }
  
      private ApiInfo apiInfo(SwaggerProperties swaggerProperties)
      {
           return new ApiInfoBuilder()
               .title(swaggerProperties.getTitle())
               .description(swaggerProperties.getDescription())
               .license(swaggerProperties.getLicense())
               .licenseUrl(swaggerProperties.getLicenseUrl())
               .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
               .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail()))
               .version(swaggerProperties.getVersion())
               .build();
      }
  }
  