解决swagger接口每次都要输入JWT Authorization认证的问题

时间:2025-03-09 20:08:54
package cn.fc.swagger2; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.RequestHandler; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.*; 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; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * api页面 / */ @Configuration @EnableSwagger2 public class SwaggerConfig { @Value("${}") private String tokenHeader; @Value("${}") private Boolean enabled; @Value("${}") private String host; private static final String SPLITOR = ","; @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .enable(enabled) .apiInfo(apiInfo()) //拼接路径,这个就相当于给swagger测试接口时,在发送的请求地址前增加这个配置的路径,实际根本就不需要,就算项目本身是配了根路径,这里也不需要配置,否则会重复 // .pathMapping("fcadmin") // 必须得配这个,不然默认就是localhost,一但部署到其他服务器上,就会出现测试接口执行时访问路径不对,例如:这个项目就出出现路径是 http://fcadmin/fcadmin/api/device .host(host) // 选择哪些路径和api会生成document .select() // 指定只扫描哪些包下面的API生成接口文档,重复写会导致一个都不会扫描 // .apis(("")) // .apis(("")) //调用重写的方法,支持扫描多个包 .apis(basePackage("" + SPLITOR + "")) .paths(Predicates.not(PathSelectors.regex("/error.*"))) .build() .securitySchemes(securitySchemes()) .securityContexts(securityContexts()); } /** * 重写basePackage方法,让swagger支持多个包扫描 * @param basePackage * @return */ public static Predicate<RequestHandler> basePackage(final String basePackage) { return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true); } private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) { return input -> { // 循环判断匹配 for (String strPackage : basePackage.split(SPLITOR)) { boolean isMatch = input.getPackage().getName().startsWith(strPackage); if (isMatch) { return true; } } return false; }; } private static Optional<? extends Class<?>> declaringClass(RequestHandler input) { return Optional.fromNullable(input.declaringClass()); } /** * 设置完成后进入SwaggerUI,右上角出现“Authorization”按钮,点击即可输入我们配置的认证参数。 * 对于不需要输入参数的接口(上文所述的包含auth的接口),在未输入Authorization参数就可以访问。 * 其他接口则将返回401错误。点击右上角“Authorization”按钮,输入配置的参数后即可通过认证访问。参数输入后全局有效,无需每个接口单独输入。 * 通过Swagger2的securitySchemes配置全局参数:如下列代码所示,securitySchemes的ApiKey中增加一个名为“Authorization”,type为“header”的参数。 * @return */ private List<ApiKey> securitySchemes() { List<ApiKey> apiKeyList = new ArrayList<>(); apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); return apiKeyList; } /** * 在Swagger2的securityContexts中通过正则表达式,设置需要使用参数的接口(或者说,是去除掉不需要使用认证参数的接口), * 如下列代码所示,通过("^(?!auth).*$"),所有包含"auth"的接口不需要使用securitySchemes。 * 即不需要使用上文中设置的名为“Authorization”,type为“header”的认证参数。 * 通俗讲,就是能匹配上的就使用默认认证,就不使用header里面的Authorization认证参数 */ private List<SecurityContext> securityContexts() { List<SecurityContext> securityContexts = new ArrayList<>(); securityContexts.add(SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.regex("^(?!auth).*$")) .build()); return securityContexts; } List<SecurityReference> defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = {authorizationScope}; List<SecurityReference> securityReferences = new ArrayList<>(); securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); return securityReferences; } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("fcadmin 接口文档") .version("1.0.0") .build(); } }