diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java index 7c50bbafa..917697b3f 100644 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java +++ b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java @@ -127,6 +127,7 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap .antMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll() // 基于 yudao.security.permit-all-urls 无需认证 .antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll() + .antMatchers("/captcha/get", "/captcha/check").permitAll() // 设置 App API 无需认证 .antMatchers(buildAppApi("/**")).permitAll() // ②:每个项目的自定义规则 diff --git a/yudao-gateway/pom.xml b/yudao-gateway/pom.xml index d38faaab6..c50b86536 100644 --- a/yudao-gateway/pom.xml +++ b/yudao-gateway/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> yudao cn.iocoder.cloud @@ -67,8 +67,23 @@ cn.iocoder.cloud yudao-spring-boot-starter-monitor + + + com.github.xiaoymin + knife4j-spring-boot-starter + + + io.swagger + swagger-annotations + + + io.springfox + springfox-boot-starter + 3.0.0 + + ${project.artifactId} diff --git a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerHandler.java b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerHandler.java new file mode 100644 index 000000000..170b1f96a --- /dev/null +++ b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerHandler.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.gateway.swagger; + + +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import springfox.documentation.swagger.web.SecurityConfiguration; +import springfox.documentation.swagger.web.SecurityConfigurationBuilder; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; +import springfox.documentation.swagger.web.UiConfiguration; +import springfox.documentation.swagger.web.UiConfigurationBuilder; + +/** + * @author zxliu + * @create 2022-10-25 11:24 + */ + +@RestController +@RequestMapping("/swagger-resources") +public class SwaggerHandler { + + @Autowired(required = false) + private SecurityConfiguration securityConfiguration; + + @Autowired(required = false) + private UiConfiguration uiConfiguration; + + private final SwaggerResourcesProvider swaggerResources; + + + @Autowired + public SwaggerHandler(SwaggerResourcesProvider swaggerResources) { + this.swaggerResources = swaggerResources; + } + + + @GetMapping("/configuration/security") + public Mono> securityConfiguration() { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), + HttpStatus.OK)); + } + + + @GetMapping("/configuration/ui") + public Mono> uiConfiguration() { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); + } + + + @SuppressWarnings("rawtypes") + @GetMapping("") + public Mono swaggerResources() { + return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); + } + +} diff --git a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java new file mode 100644 index 000000000..0a1c60183 --- /dev/null +++ b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.gateway.swagger; + +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.support.NameUtils; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; +import springfox.documentation.swagger.web.SwaggerResource; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; + +/** + * @author zxliu + * @create 2022-10-25 11:23 + */ + +@Component +@Primary +@AllArgsConstructor +public class SwaggerProvider implements SwaggerResourcesProvider { + + private final RouteLocator routeLocator; + private final GatewayProperties gatewayProperties; + + + @Override + public List get() { + List resources = new ArrayList<>(); + List routes = new ArrayList<>(); + routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); + gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())) + .forEach(route -> route.getPredicates().stream() + .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())) + .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(), + predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") + .replace("**", "v2/api-docs")))) + ); + + return resources; + } + + + private SwaggerResource swaggerResource(String name, String location) { + SwaggerResource swaggerResource = new SwaggerResource(); + swaggerResource.setName(name); + swaggerResource.setLocation(location); + swaggerResource.setSwaggerVersion("2.0"); + return swaggerResource; + } + +} diff --git a/yudao-gateway/src/main/resources/application.yaml b/yudao-gateway/src/main/resources/application.yaml index 29d9576a6..5689d0ccc 100644 --- a/yudao-gateway/src/main/resources/application.yaml +++ b/yudao-gateway/src/main/resources/application.yaml @@ -5,25 +5,41 @@ spring: cloud: # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 gateway: + discovery: + locator: + # gateway开启服务注册和发现的功能, + enabled: true + # 将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了) + lowerCaseServiceId: true # 路由配置项,对应 RouteDefinition 数组 routes: - id: system-admin-api # 路由的编号 uri: grayLb://system-server predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 - - Path=/admin-api/system/** + - Path=/admin-api/system/**,/captcha/** + filters: + - RewritePath=/admin-api/system/v2/api-docs, /v2/api-docs - id: system-app-api # 路由的编号 uri: grayLb://system-server predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 - Path=/app-api/system/** + filters: + - RewritePath=/app-api/system/v2/api-docs, /v2/api-docs - id: infra-admin-api # 路由的编号 uri: grayLb://infra-server predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 - Path=/admin-api/infra/** + filters: + - RewritePath=/admin-api/infram/v2/api-docs, /v2/api-docs - id: infra-app-api # 路由的编号 uri: grayLb://infra-server predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 - Path=/app-api/infra/** + filters: + - RewritePath=/app-api/infra/v2/api-docs, /v2/api-docs - id: bpm-admin-api # 路由的编号 uri: grayLb://bpm-server predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 - Path=/admin-api/bpm/** + filters: + - RewritePath=/admin-api/bpm/v2/api-docs, /v2/api-docs