package com.test.gateway.filter; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.qs.gateway.filter.xss.EscapeUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.annotation.Order; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequestDecorator; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import space.tryanything.kit.security.oauth.OAuth2Key; import java.nio.charset.StandardCharsets; import java.util.stream.Collectors; @Slf4j @Component @Order(3) public class HttpRequestFilter implements GlobalFilter { private final ObjectMapper mapper = new ObjectMapper(); @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); String method = request.getMethodValue().toUpperCase(); if("GET".equalsIgnoreCase(method)){ try { skyWalkInput(mapper.writeValueAsString(request.getQueryParams()),exchange); } catch (JsonProcessingException e) { log.error(e.getMessage(), e); } ServerHttpRequest mutateReq = new ServerHttpRequestDecorator(request) { @Override public MultiValueMap<String, String> getQueryParams() { final MultiValueMap<String, String> parent = super.getQueryParams(); final MultiValueMap<String, String> now = new LinkedMultiValueMap<>(parent.size()); parent.forEach((key, value) -> now.addAll(key, value.stream() .map(EscapeUtil::clean) .collect(Collectors.toList()))); return now; } }; return chain.filter(exchange.mutate().request(mutateReq).build()); } return requestDecorator(exchange,chain); } private Mono<Void> requestDecorator(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); final HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.putAll(request.getHeaders()); httpHeaders.remove(HttpHeaders.CONTENT_LENGTH); httpHeaders.set(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON_VALUE); return DataBufferUtils.join(request.getBody()).flatMap(dataBuffer -> { byte[] bytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(bytes); String bodyStr = new String(bytes, StandardCharsets.UTF_8); skyWalkInput(bodyStr,exchange); exchange.getAttributes().put("POST_BODY", bodyStr); DataBufferUtils.release(dataBuffer); Flux<DataBuffer> cachedFlux = Flux.defer(() -> { DataBuffer buffer = response.bufferFactory().wrap(bytes); return Mono.just(buffer); }); ServerHttpRequest mutateReq = new ServerHttpRequestDecorator(request) { @Override public Flux<DataBuffer> getBody() { return cachedFlux; } }; return chain.filter(exchange.mutate().request(mutateReq).build()); }); } private void skyWalkInput(String body,ServerWebExchange exchange){ //构造请求的方法&URL&参数 StringBuilder sb = new StringBuilder("curl") .append(" -X ").append(exchange.getRequest().getMethod()) .append(" ").append(exchange.getRequest().getPath().pathWithinApplication().value()); if(StringUtils.hasLength(body)){ sb.append("?").append(body); } //构造header HttpHeaders header = exchange.getRequest().getHeaders(); String authorization = header.getFirst(OAuth2Key.AUTHORIZATION_KEY); sb.append(" -H '").append("authorization:").append(authorization).append("'"); String contentType = header.getFirst(HttpHeaders.CONTENT_TYPE); sb.append(" -H '").append("Content-Type:").append(contentType).append("'"); } }
版权声明:本文为chenrisheng1原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。