处理Swagger3问题

This commit is contained in:
2023-10-16 16:30:47 +08:00
parent 1b20b0c34c
commit cc567b98e6
2 changed files with 323 additions and 303 deletions

View File

@ -1,141 +1,161 @@
package com.jnssd.config; // package com.jnssd.config;
//
import org.springframework.context.annotation.Bean; // import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; // import org.springframework.context.annotation.Configuration;
import org.springframework.util.AntPathMatcher; // import org.springframework.util.AntPathMatcher;
import springfox.documentation.builders.ApiInfoBuilder; // import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.OAuthBuilder; // import springfox.documentation.builders.OAuthBuilder;
import springfox.documentation.builders.PathSelectors; // import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; // import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi; // import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.*; // import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType; // import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext; // import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket; // import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.ApiKeyVehicle; // import springfox.documentation.swagger.web.ApiKeyVehicle;
import springfox.documentation.swagger.web.SecurityConfiguration; // import springfox.documentation.swagger2.annotations.EnableSwagger2;
import springfox.documentation.swagger.web.SecurityConfigurationBuilder; //
import springfox.documentation.swagger2.annotations.EnableSwagger2; // import java.util.ArrayList;
// import java.util.Arrays;
import java.util.ArrayList; // import java.util.Collections;
import java.util.Arrays; // import java.util.List;
import java.util.Collections; //
import java.util.List; // /**
// * <h3>spring-boot-openapi</h3>
/** // * <p></p>
* <h3>spring-boot-openapi</h3> // *
* <p></p> // * @author zxj
* // * @since 2023-10-12 17:13:09
* @author zxj // */
* @since 2023-10-12 17:13:09 // @Configuration
*/ // @EnableSwagger2
@Configuration // @EnableOpenApi
@EnableSwagger2 // public class SwaggerConfig {
@EnableOpenApi //
public class SwaggerConfig { // private final String[] securitySchemeNames = {"ApiKey模式", "basicAuth模式", "oauth2的Password模式", "oauth2的authorization_code模式", "oauth2的implicit模式", "oauth2的clientCredentials模式"};
//
private final String[] securitySchemeNames = {"ApiKey模式", "basicAuth模式", "oauth2的Password模式", "oauth2的authorization_code模式", "oauth2的implicit模式", "oauth2的clientCredentials模式"}; //
// @Bean
// public Docket api() {
@Bean // return new Docket(DocumentationType.SWAGGER_2)
public Docket api() { // .apiInfo(apiInfo()).select()
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() // // 扫描特定包
// 扫描特定包 // // 扫描所有有注解的api用这种方式更灵活
// 扫描所有有注解的api用这种方式更灵活 // // .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) // //.apis(RequestHandlerSelectors.any())
//.apis(RequestHandlerSelectors.any()) // .apis(RequestHandlerSelectors.basePackage("com.jnssd"))
.apis(RequestHandlerSelectors.basePackage("com.jnssd")).paths(PathSelectors.any()).build().securitySchemes(initSecuritySchemeList()).securityContexts(Collections.singletonList(securityContext())); // .paths(PathSelectors.any())
} // .build()
// .securitySchemes(initSecuritySchemeList())
public ApiInfo apiInfo() { // .securityContexts(Collections.singletonList(securityContext()));
return new ApiInfoBuilder().title("Swagger项目测试").description("novel项目接口文档").build(); // }
} //
// public ApiInfo apiInfo() {
// return new ApiInfoBuilder()
public List<SecurityScheme> initSecuritySchemeList() { // .title("Swagger项目测试")
List<SecurityScheme> list = new ArrayList<>(); // .description("novel项目接口文档")
list.add(securitySchemeBasicAuth()); // .build();
list.add(securitySchemeApiKey()); // }
//
// oauth2下的几个模式配置 //
// 1. 密码模式 // /**
list.add(securitySchemeOAuth2Password()); // * 初始化安全方案
// 2. 客户端模式 // *
list.add(securitySchemeOAuth2ClientCredentials()); // * @return
// 3. 授权码模式 // */
list.add(securitySchemeOAuth2AuthorizationCode()); // public List<SecurityScheme> initSecuritySchemeList() {
// 4. 简化模式 // List<SecurityScheme> list = new ArrayList<>();
list.add(securitySchemeOAuth2Implicit()); // list.add(securitySchemeBasicAuth());
return list; // list.add(securitySchemeApiKey());
} //
// // oauth2下的几个模式配置
// ApiKey模式 // // 1. 密码模式
private SecurityScheme securitySchemeApiKey() { // list.add(securitySchemeOAuth2Password());
return new ApiKey("ApiKey模式", "Authorization", ApiKeyVehicle.HEADER.getValue()); // // 2. 客户端模式
} // list.add(securitySchemeOAuth2ClientCredentials());
// // 3. 授权码模式
// basicAuth模式 // list.add(securitySchemeOAuth2AuthorizationCode());
private SecurityScheme securitySchemeBasicAuth() { // // 4. 简化模式
return new BasicAuth("basicAuth模式"); // list.add(securitySchemeOAuth2Implicit());
} // return list;
// }
// oauth2下面的password模式 //
private SecurityScheme securitySchemeOAuth2Password() { // // ApiKey模式
List<GrantType> grantTypes = new ArrayList<>(); // private SecurityScheme securitySchemeApiKey() {
grantTypes.add(new ResourceOwnerPasswordCredentialsGrant("/oauth/token")); // return new ApiKey("ApiKey模式", "Authorization", ApiKeyVehicle.HEADER.getValue());
return new OAuthBuilder().name("oauth2的Password模式").scopes(scopes()).grantTypes(grantTypes).build(); // }
} //
// // basicAuth模式
// oauth2下面的authorization_code模式 // private SecurityScheme securitySchemeBasicAuth() {
private SecurityScheme securitySchemeOAuth2AuthorizationCode() { // return new BasicAuth("basicAuth模式");
List<GrantType> grantTypes = new ArrayList<>(); // }
TokenRequestEndpoint tokenRequestEndpoint = new TokenRequestEndpoint("/oauth/authorize", "", ""); //
TokenEndpoint tokenEndpoint = new TokenEndpoint("/oauth/token", "token"); // // oauth2下面的password模式
grantTypes.add(new AuthorizationCodeGrant(tokenRequestEndpoint, tokenEndpoint)); // private SecurityScheme securitySchemeOAuth2Password() {
return new OAuthBuilder().name("oauth2的authorization_code模式").scopes(scopes()).grantTypes(grantTypes).build(); // List<GrantType> grantTypes = new ArrayList<>();
} // grantTypes.add(new ResourceOwnerPasswordCredentialsGrant("/oauth/token"));
// return new OAuthBuilder().name("oauth2的Password模式").scopes(scopes()).grantTypes(grantTypes).build();
// oauth2下面的implicit模式 // }
private SecurityScheme securitySchemeOAuth2Implicit() { //
List<GrantType> grantTypes = new ArrayList<>(); // // oauth2下面的authorization_code模式
ImplicitGrant implicitGrant = new ImplicitGrant(new LoginEndpoint("/oauth/authorize"), "token"); // private SecurityScheme securitySchemeOAuth2AuthorizationCode() {
grantTypes.add(implicitGrant); // List<GrantType> grantTypes = new ArrayList<>();
return new OAuthBuilder().name("oauth2的implicit模式").scopes(scopes()).grantTypes(grantTypes).build(); // TokenRequestEndpoint tokenRequestEndpoint = new TokenRequestEndpoint("/oauth/authorize", "", "");
} // TokenEndpoint tokenEndpoint = new TokenEndpoint("/oauth/token", "token");
// grantTypes.add(new AuthorizationCodeGrant(tokenRequestEndpoint, tokenEndpoint));
// oauth2下面的ClientCredentials模式 // return new OAuthBuilder().name("oauth2的authorization_code模式").scopes(scopes()).grantTypes(grantTypes).build();
private SecurityScheme securitySchemeOAuth2ClientCredentials() { // }
List<GrantType> grantTypes = new ArrayList<>(); //
grantTypes.add(new ClientCredentialsGrant("/oauth/token")); // // oauth2下面的implicit模式
return new OAuthBuilder().name("oauth2的clientCredentials模式").scopes(scopes()).grantTypes(grantTypes).build(); // private SecurityScheme securitySchemeOAuth2Implicit() {
} // List<GrantType> grantTypes = new ArrayList<>();
// ImplicitGrant implicitGrant = new ImplicitGrant(new LoginEndpoint("/oauth/authorize"), "token");
private SecurityContext securityContext() { // grantTypes.add(implicitGrant);
List<SecurityReference> list = new ArrayList<>(); // return new OAuthBuilder().name("oauth2的implicit模式").scopes(scopes()).grantTypes(grantTypes).build();
Arrays.stream(securitySchemeNames).forEach(s -> list.add(new SecurityReference(s, new AuthorizationScope[0]))); // }
return SecurityContext.builder().operationSelector(operationContext -> { //
System.out.println("operationContext" + operationContext); // // oauth2下面的ClientCredentials模式
// 除了get方法其他方法都要校验 // private SecurityScheme securitySchemeOAuth2ClientCredentials() {
// return !operationContext.httpMethod().name().equals("GET"); // List<GrantType> grantTypes = new ArrayList<>();
// grantTypes.add(new ClientCredentialsGrant("/oauth/token"));
// 通过地址模糊匹配 // return new OAuthBuilder().name("oauth2的clientCredentials模式").scopes(scopes()).grantTypes(grantTypes).build();
AntPathMatcher pathMatcher = new AntPathMatcher(); // }
String path = operationContext.requestMappingPattern(); //
return pathMatcher.match("/menu/**", path) || pathMatcher.match("/user/**", path); // /**
}).securityReferences(list).build(); // * oauth2访问范围
} // *
// * @return
private List<AuthorizationScope> scopes() { // */
List<AuthorizationScope> list = new ArrayList<>(); // private List<AuthorizationScope> scopes() {
list.add(new AuthorizationScope("read_scope", "Grants read access")); // List<AuthorizationScope> list = new ArrayList<>();
list.add(new AuthorizationScope("write_scope", "Grants write access")); // list.add(new AuthorizationScope("read_scope", "Grants read access"));
list.add(new AuthorizationScope("admin_scope", "Grants read write and delete access")); // list.add(new AuthorizationScope("write_scope", "Grants write access"));
return list; // list.add(new AuthorizationScope("admin_scope", "Grants read write and delete access"));
} // return list;
// }
@Bean //
public SecurityConfiguration security() { // /**
return SecurityConfigurationBuilder.builder().clientId("").clientSecret("").realm("*").appName("").scopeSeparator("").useBasicAuthenticationWithAccessCodeGrant(false).build(); // * 配置接口下哪些需要实现安全访问
} // * @return
// */
} // private SecurityContext securityContext() {
// List<SecurityReference> list = new ArrayList<>();
// // 这里的SecurityReference第一个参数值必须和SecurityScheme的name值一致
// Arrays.stream(securitySchemeNames).forEach(name -> list.add(new SecurityReference(name, new AuthorizationScope[0])));
// return SecurityContext.builder().operationSelector(operationContext -> {
// System.out.println("operationContext" + operationContext);
// // 除了get方法其他方法都要校验
// // return !operationContext.httpMethod().name().equals("GET");
//
// // 通过地址模糊匹配
// AntPathMatcher pathMatcher = new AntPathMatcher();
// String path = operationContext.requestMappingPattern();
// return pathMatcher.match("/menu/**", path) || pathMatcher.match("/user/**", path);
// }).securityReferences(list).build();
// }
// // @Bean
// // public SecurityConfiguration security() {
// // return SecurityConfigurationBuilder.builder().clientId("").clientSecret("").realm("*").appName("").scopeSeparator("").useBasicAuthenticationWithAccessCodeGrant(false).build();
// // }
//
// }

View File

@ -1,61 +1,64 @@
// package com.jnssd.config; package com.jnssd.config;
//
// import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
// import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
// import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
// import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ApiInfoBuilder;
// import springfox.documentation.builders.OpenIdConnectSchemeBuilder; import springfox.documentation.builders.OpenIdConnectSchemeBuilder;
// import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.PathSelectors;
// import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.RequestHandlerSelectors;
// import springfox.documentation.oas.annotations.EnableOpenApi; import springfox.documentation.oas.annotations.EnableOpenApi;
// import springfox.documentation.service.*; import springfox.documentation.service.*;
// import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
// import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spi.service.contexts.SecurityContext;
// import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
//
// import java.util.ArrayList; import java.util.ArrayList;
// import java.util.Collections; import java.util.Arrays;
// import java.util.List; import java.util.Collections;
// import java.util.List;
// /**
// * <h3>spring-boot-openapi</h3> /**
// * <p>配置openapi</p> * <h3>spring-boot-openapi</h3>
// * * <p>配置openapi</p>
// * @author zxj *
// * @since 2023-10-13 14:29:58 * @author zxj
// */ * @since 2023-10-13 14:29:58
// */
// @Configuration
// @EnableOpenApi @Configuration
// public class SwaggerOpenApiConfig { @EnableOpenApi
// public class SwaggerOpenApiConfig {
// @Bean
// public Docket api() { private final String[] securitySchemeNames = {"JWT模式", "ApiKey模式", "OIDC模式", "oauth2的Password模式", "oauth2的authorization_code模式", "oauth2的implicit模式", "oauth2的clientCredentials模式"};
// return new Docket(DocumentationType.OAS_30)
// .apiInfo(apiInfo()) @Bean
// .select() public Docket api() {
// // 扫描特定包 return new Docket(DocumentationType.OAS_30)
// // 扫描所有有注解的api用这种方式更灵活 .apiInfo(apiInfo())
// // .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .select()
// //.apis(RequestHandlerSelectors.any()) // 扫描特定包
// .apis(RequestHandlerSelectors.basePackage("com.jnssd")) // 扫描所有有注解的api用这种方式更灵活
// .paths(PathSelectors.any()) // .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// .build() //.apis(RequestHandlerSelectors.any())
// .securitySchemes(initSecuritySchemeList()) .apis(RequestHandlerSelectors.basePackage("com.jnssd"))
// .securityContexts(Collections.singletonList(securityContext())); .paths(PathSelectors.any())
// } .build()
// .securitySchemes(initSecuritySchemeList())
// public ApiInfo apiInfo() { .securityContexts(Collections.singletonList(securityContext()));
// return new ApiInfoBuilder() }
// .title("Swagger项目测试")
// .description("novel项目接口文档") public ApiInfo apiInfo() {
// .build(); return new ApiInfoBuilder()
// } .title("Swagger项目测试")
// .description("novel项目接口文档")
// private List<SecurityScheme> initSecuritySchemeList() { .build();
// }
// List<SecurityScheme> list = new ArrayList<>();
// list.add(httpAuthenticationScheme()); private List<SecurityScheme> initSecuritySchemeList() {
List<SecurityScheme> list = new ArrayList<>();
list.add(httpAuthenticationScheme());
// list.add(securitySchemeApiKey()); // list.add(securitySchemeApiKey());
// list.add(securitySchemeOpenIdConnect()); // list.add(securitySchemeOpenIdConnect());
// //
@ -64,99 +67,96 @@
// list.add(securitySchemeOauth2implicit()); // list.add(securitySchemeOauth2implicit());
// list.add(securitySchemeOauth2Password()); // list.add(securitySchemeOauth2Password());
// list.add(securitySchemeOauth2AuthorizationCode()); // list.add(securitySchemeOauth2AuthorizationCode());
// return list; return list;
// } }
//
// private SecurityScheme httpAuthenticationScheme() { // basic模式或者JWT模式
// return HttpAuthenticationScheme.JWT_BEARER_BUILDER.name("JWT的值").build(); private SecurityScheme httpAuthenticationScheme() {
// } // 之前的basic模式
// // return HttpAuthenticationScheme.BASIC_AUTH_BUILDER.name("basic模式").build();
// // ApiKey模式 return HttpAuthenticationScheme.JWT_BEARER_BUILDER.name("JWT模式").build();
// private SecurityScheme securitySchemeApiKey() { }
// return new ApiKey("Authorization授权", "Authorization", "header");
// } // ApiKey模式
// private SecurityScheme securitySchemeApiKey() {
// // OpenIdConnect return new ApiKey("ApiKey模式", "Authorization", "header");
// }
// // return new OpenIdConnectSchemeBuilder()
// // .name("OpenId授权") // OpenIdConnect
// // .description("OpenIdConnect授权配置")
// // .openIdConnectUrl("https://your-openid-connect-url")
// // .build();
// private SecurityScheme securitySchemeOpenIdConnect() {
// // Swagger配置 OpenIdConnect
// return new OpenIdConnectSchemeBuilder() // return new OpenIdConnectSchemeBuilder()
// .name("OpenIdConnect授权") // .name("OpenId授权")
// .description("OpenIdConnect授权配置") // .description("OpenIdConnect授权配置")
// .openIdConnectUrl("https://your-openid-connect-url") // .openIdConnectUrl("https://your-openid-connect-url")
// .build(); // .build();
// } private SecurityScheme securitySchemeOpenIdConnect() {
// // Swagger配置 OpenIdConnect
// // 客户端模式 return new OpenIdConnectSchemeBuilder()
// private SecurityScheme securitySchemeOauth2ClientCredentials() { .name("OpenIdConnect授权")
// return OAuth2Scheme.OAUTH2_CLIENT_CREDENTIALS_FLOW_BUILDER .description("OpenIdConnect授权配置")
// .name("客户端模式") .openIdConnectUrl("https://your-openid-connect-url")
// .tokenUrl("/oauth/authorize") .build();
// .scopes(scopes()) }
// .build();
// } // oauth2下面的authorization_code模式
// private SecurityScheme securitySchemeOauth2AuthorizationCode() {
// // 隐式模式 return OAuth2Scheme.OAUTH2_AUTHORIZATION_CODE_FLOW_BUILDER
// private SecurityScheme securitySchemeOauth2implicit() { .name("oauth2的authorization_code模式")
// return OAuth2Scheme.OAUTH2_IMPLICIT_FLOW_BUILDER .authorizationUrl("/oauth/authorize")
// .name("简化模式") .tokenUrl("/oauth/token")
// .authorizationUrl("/oauth/authorize") .scopes(scopes())
// .scopes(scopes()) .build();
// .build(); }
// }
// // oauth2下面的implicit模式
// // 密码模式 private SecurityScheme securitySchemeOauth2implicit() {
// private SecurityScheme securitySchemeOauth2Password() { return OAuth2Scheme.OAUTH2_IMPLICIT_FLOW_BUILDER
// return OAuth2Scheme.OAUTH2_PASSWORD_FLOW_BUILDER .name("oauth2的implicit模式")
// .name("密码模式") .authorizationUrl("/oauth/authorize")
// .tokenUrl("/oauth/token") .scopes(scopes())
// .scopes(scopes()) .build();
// .build(); }
// }
// // oauth2下面的ClientCredentials模式
// // 授权码模式 private SecurityScheme securitySchemeOauth2ClientCredentials() {
// private SecurityScheme securitySchemeOauth2AuthorizationCode() { return OAuth2Scheme.OAUTH2_CLIENT_CREDENTIALS_FLOW_BUILDER
// return OAuth2Scheme.OAUTH2_AUTHORIZATION_CODE_FLOW_BUILDER .name("oauth2的clientCredentials模式")
// .name("授权码模式") .tokenUrl("/oauth/authorize")
// .authorizationUrl("/oauth/authorize") .scopes(scopes())
// .tokenUrl("/oauth/token") .build();
// .scopes(scopes()) }
// .build();
// } // oauth2下面的password模式
// private SecurityScheme securitySchemeOauth2Password() {
// private List<AuthorizationScope> scopes() { return OAuth2Scheme.OAUTH2_PASSWORD_FLOW_BUILDER
// List<AuthorizationScope> list = new ArrayList<>(); .name("oauth2的Password模式")
// list.add(new AuthorizationScope("read_scope", "Grants read access")); .tokenUrl("/oauth/token")
// list.add(new AuthorizationScope("write_scope", "Grants write access")); .scopes(scopes())
// list.add(new AuthorizationScope("admin_scope", "Grants read write and delete access")); .build();
// return list; }
// }
//
// private SecurityContext securityContext() { private List<AuthorizationScope> scopes() {
// return SecurityContext.builder() List<AuthorizationScope> list = new ArrayList<>();
// .securityReferences(defaultAuth()) list.add(new AuthorizationScope("read_scope", "Grants read access"));
// .operationSelector(operationContext -> { list.add(new AuthorizationScope("write_scope", "Grants write access"));
// System.out.println("operationContext" + operationContext); list.add(new AuthorizationScope("admin_scope", "Grants read write and delete access"));
// // 除了get方法其他方法都要校验 return list;
// // return !operationContext.httpMethod().name().equals("GET"); }
//
// // 通过地址模糊匹配 private SecurityContext securityContext() {
// AntPathMatcher pathMatcher = new AntPathMatcher(); List<SecurityReference> list = new ArrayList<>();
// String path = operationContext.requestMappingPattern(); // 这里的SecurityReference第一个参数值必须和SecurityScheme的name值一致
// return pathMatcher.match("/menu/**", path) || pathMatcher.match("/user/**", path); Arrays.stream(securitySchemeNames).forEach(name -> list.add(new SecurityReference(name, new AuthorizationScope[0])));
// }) return SecurityContext.builder().operationSelector(operationContext -> {
// .build(); System.out.println("operationContext" + operationContext);
// } // 除了get方法其他方法都要校验
// // return !operationContext.httpMethod().name().equals("GET");
// private List<SecurityReference> defaultAuth() {
// AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); // 通过地址模糊匹配
// AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; AntPathMatcher pathMatcher = new AntPathMatcher();
// authorizationScopes[0] = authorizationScope; String path = operationContext.requestMappingPattern();
// return Collections.singletonList(new SecurityReference("密码模式", authorizationScopes)); return pathMatcher.match("/menu/**", path) || pathMatcher.match("/user/**", path);
// } }).securityReferences(list).build();
// } }
}