feat:add unauth api
This commit is contained in:
parent
37a1ed6310
commit
64092f405f
@ -48,6 +48,11 @@
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.52</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@ -59,6 +64,7 @@
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
|
@ -0,0 +1,65 @@
|
||||
package com.ensign.ensigngateway.conf;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @Date: 2024/10/30 9:30
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CorsResponseHeaderFilter.class);
|
||||
|
||||
private static final String ANY = "*";
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
// 指定此过滤器位于NettyWriteResponseFilter之后
|
||||
// 即待处理完响应体后接着处理响应头
|
||||
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("serial")
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
|
||||
exchange.getResponse().getHeaders().entrySet().stream()
|
||||
.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
|
||||
.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)
|
||||
|| kv.getKey().equals(HttpHeaders.VARY)))
|
||||
.forEach(kv ->
|
||||
{
|
||||
// Vary只需要去重即可
|
||||
if(kv.getKey().equals(HttpHeaders.VARY))
|
||||
kv.setValue(kv.getValue().stream().distinct().collect(Collectors.toList()));
|
||||
else{
|
||||
List<String> value = new ArrayList<>();
|
||||
if(kv.getValue().contains(ANY)){ //如果包含*,则取*
|
||||
value.add(ANY);
|
||||
kv.setValue(value);
|
||||
}else{
|
||||
value.add(kv.getValue().get(0)); // 否则默认取第一个
|
||||
kv.setValue(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.ensign.ensigngateway.conf;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.reactive.CorsWebFilter;
|
||||
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @Date: 2024/10/30 9:21
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
|
||||
@Configuration
|
||||
public class GlobalCorsConfig {
|
||||
@Bean
|
||||
public CorsWebFilter corsWebFilter() {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
// 这里仅为了说明问题,配置为放行所有域名,生产环境请对此进行修改
|
||||
config.addAllowedOriginPattern("*");
|
||||
// 放行的请求头
|
||||
config.addAllowedHeader("*");
|
||||
// 放行的请求方式,主要有:GET, POST, PUT, DELETE, OPTIONS
|
||||
config.addAllowedMethod("*");
|
||||
// 暴露头部信息
|
||||
config.addExposedHeader("*");
|
||||
// 是否发送cookie
|
||||
config.setAllowCredentials(true);
|
||||
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
return new CorsWebFilter(source);
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package com.ensign.ensigngateway.conf;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @Date: 2024/10/30 9:34
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class GlobalResponseLogFilter implements GlobalFilter, Ordered {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
// 打印请求路径
|
||||
String path = request.getPath().pathWithinApplication().value();
|
||||
return chain.filter(exchange).then(
|
||||
Mono.fromRunnable(() -> {
|
||||
MultiValueMap<String, String> queryParams = request.getQueryParams();
|
||||
String requestUrl = UriComponentsBuilder.fromPath(path).queryParams(queryParams).build().toUriString();
|
||||
|
||||
// 构建成一条长日志
|
||||
StringBuilder responseLog = new StringBuilder(200);
|
||||
// 日志参数
|
||||
List<Object> responseArgs = new ArrayList<>();
|
||||
responseLog.append("\n\n================ Gateway Response Start ================\n");
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
// 状态码个path占位符: 200 get: /xxx/xxx/xxx?a=b
|
||||
responseLog.append("<=== {} {}: {}\n");
|
||||
// 参数
|
||||
String requestMethod = request.getMethod().toString();
|
||||
responseArgs.add(Objects.requireNonNull(response.getStatusCode()).value());
|
||||
responseArgs.add(requestMethod);
|
||||
responseArgs.add(requestUrl);
|
||||
|
||||
// 打印请求头
|
||||
HttpHeaders headers = response.getHeaders();
|
||||
headers.forEach((headerName, headerValue) -> {
|
||||
responseLog.append("===Headers=== {}: {}\n");
|
||||
responseArgs.add(headerName);
|
||||
responseArgs.add(String.join(StringUtils.join(headerValue.toArray())));
|
||||
});
|
||||
|
||||
responseLog.append("================ Gateway Response End =================\n");
|
||||
// 打印执行时间
|
||||
log.info(responseLog.toString(), responseArgs.toArray());
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
}
|
||||
}
|
@ -7,14 +7,12 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
@ -36,10 +34,8 @@ public class ProxyFilter implements GlobalFilter {
|
||||
String path = exchange.getRequest().getURI().getPath();
|
||||
log.info("path {}", path);
|
||||
|
||||
String userId = exchange.getRequest().getHeaders().getFirst("userid");
|
||||
if (path.startsWith("/ierp/kapi/")) {
|
||||
String userId = exchange.getRequest().getHeaders().getFirst("userid");
|
||||
|
||||
|
||||
log.info("userId: {}", userId);
|
||||
|
||||
return webClient.get()
|
||||
@ -48,6 +44,7 @@ public class ProxyFilter implements GlobalFilter {
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.retrieve()
|
||||
.onStatus(HttpStatusCode::is4xxClientError, response -> {
|
||||
log.error(response.statusCode().toString());
|
||||
return Mono.error(new RuntimeException("Unauthorized"));
|
||||
})
|
||||
.bodyToMono(String.class)
|
||||
@ -59,6 +56,7 @@ public class ProxyFilter implements GlobalFilter {
|
||||
String token = respJson.getString("data");
|
||||
exchange.getRequest().mutate()
|
||||
.header("access_token", token)
|
||||
.header("userid", userId)
|
||||
.build();
|
||||
log.info("token: {}", token);
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
package com.ensign.ensigngateway.conf;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @Date: 2024/10/30 9:32
|
||||
* @Created: by ZZSLL
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RequestLogFilter implements GlobalFilter, Ordered {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
// 打印请求路径
|
||||
String path = request.getPath().pathWithinApplication().value();
|
||||
// 打印请求url
|
||||
String requestUrl = this.getOriginalRequestUrl(exchange);
|
||||
|
||||
// **构建成一条长 日志,避免并发下日志错乱**
|
||||
StringBuilder reqLog = new StringBuilder(200);
|
||||
// 日志参数
|
||||
List<Object> reqArgs = new ArrayList<>();
|
||||
reqLog.append("\n\n================ Gateway Request Start ================\n");
|
||||
// 打印路由添加占位符
|
||||
reqLog.append("===> {}: {}\n");
|
||||
// 参数
|
||||
String requestMethod = request.getMethod().name();
|
||||
reqArgs.add(requestMethod);
|
||||
reqArgs.add(requestUrl);
|
||||
|
||||
// 打印请求头
|
||||
HttpHeaders headers = request.getHeaders();
|
||||
headers.forEach((headerName, headerValue) -> {
|
||||
reqLog.append("===Headers=== {}: {}\n");
|
||||
reqArgs.add(headerName);
|
||||
});
|
||||
|
||||
reqLog.append("================ Gateway Request End =================\n");
|
||||
// 打印执行时间
|
||||
log.info(reqLog.toString(), reqArgs.toArray());
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
private String getOriginalRequestUrl(ServerWebExchange exchange) {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
LinkedHashSet<URI> uris = exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
|
||||
URI requestUri = uris.stream().findFirst().orElse(request.getURI());
|
||||
MultiValueMap<String, String> queryParams = request.getQueryParams();
|
||||
return UriComponentsBuilder.fromPath(requestUri.getRawPath()).queryParams(queryParams).build().toUriString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@ spring:
|
||||
|
||||
cloud:
|
||||
gateway:
|
||||
# globalcors:
|
||||
# add-to-simple-url-handler-mapping: true
|
||||
|
||||
routes:
|
||||
- id: proxy_route
|
||||
uri: ${kingdee.test-inner-end-point}
|
||||
@ -12,6 +15,13 @@ spring:
|
||||
filters:
|
||||
- RewritePath=/crm-api/proxy/do/(?<segment>.*), /${segment}
|
||||
|
||||
- id: system-app-api
|
||||
uri: http://127.0.0.1:38080
|
||||
predicates:
|
||||
- Path=/admin-api/**
|
||||
filters:
|
||||
- RewritePath=/admin-api/(?<segment>.*), /${segment}
|
||||
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 20MB
|
||||
@ -24,4 +34,4 @@ kingdee:
|
||||
test-inner-end-point: 'http://10.64.112.152:8022'
|
||||
prod-public-end-point: 'http://122.4.221.130:8022'
|
||||
prod-inner-end-point: 'http://10.64.111.134:8022'
|
||||
local: 'http://127.0.0.1:48080'
|
||||
local: 'http://127.0.0.1:38080'
|
||||
|
@ -55,4 +55,35 @@ public class ProxyController {
|
||||
public void proxyRead(@RequestParam String path, HttpServletResponse response) throws AllKingdeeException, IOException {
|
||||
proxyService.doGetImage(path, response);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/unauth/do/**", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
@Operation(summary = "转发接口")
|
||||
@PermitAll
|
||||
public void proxyUnAuth(HttpServletRequest request, HttpServletResponse response) throws IOException, URISyntaxException {
|
||||
String requestURI = request.getRequestURI();
|
||||
String[] unAuthPath = new String[]{
|
||||
// 市场活动详情
|
||||
"/crm-api/proxy/unauth/do/ierp/kapi/v2/yem/yem_receipt/yem_crm_marketactivity/getMarketactivities",
|
||||
|
||||
// 获取机型
|
||||
"/crm-api/proxy/unauth/do/ierp/kapi/v2/yem/yem_crmbasic/yem_crm_region/CRM_yem_crm_region",
|
||||
|
||||
// 活动登记
|
||||
"/crm-api/proxy/unauth/do/ierp/kapi/v2/yem/yem_receipt/api/MarketQRCodeAdd"
|
||||
};
|
||||
if (isAuthorized(requestURI, unAuthPath)) {
|
||||
proxyService.doProxy(request, response);
|
||||
} else {
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAuthorized(String requestURI, String[] unAuthPath) {
|
||||
for (String path : unAuthPath) {
|
||||
if (requestURI.equals(path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,9 @@ public class ProxyService {
|
||||
URI uri = new URI(request.getRequestURI());
|
||||
String path = uri.getPath();
|
||||
String query = request.getQueryString();
|
||||
if (path.contains("/unauth")) {
|
||||
path = path.replace("/unauth", "");
|
||||
}
|
||||
String target = initBasePath() + path.replace("/crm-api/proxy/do", "");
|
||||
String accessToken;
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user