1 入参解密 解密方法自己实现
package com.xhd.gateway.filter;
import com.xhd.common.cores.exception.ServiceException;
import com.xhd.common.cores.rsa.AesRsaUtil;
import com.xhd.gateway.config.properties.EncryptProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
/**
*@Author:luyongcheng
*@Date:2024/8/27 10:50
*/
@Configuration
@Slf4j
public class RequestEncryptFilter implements GlobalFilter, Ordered {
@Autowired
private EncryptProperties encryptProperties;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// 请求方法
HttpMethod method = request.getMethod();
if (!encryptProperties.getIsEncrypt() || method != HttpMethod.POST) {
return chain.filter(exchange); // 如果不需要解密,直接传递
}
// 获取请求体并解密
ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
Mono<String> modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {
try {
String decryptStr = AesRsaUtil.decrypt(body, encryptProperties.getPrivateKeyFront());
log.info("请求url:" + request.getURI());
log.info("请求参数解密成功:" + decryptStr);
return Mono.just(decryptStr);
} catch (Exception e) {
log.error("请求参数解密失败,url: " + request.getURI(), e);
throw new ServiceException("请求参数解密失败");
}
});
// 创建新的 ServerHttpRequestDecorator,修改请求体
return modifiedBody.flatMap(decryptedBody -> {
// 修改请求体并构建新的请求头
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
headers.remove(HttpHeaders.CONTENT_LENGTH); // 移除旧的 Content-Length
// 使用从解密结果生成的新请求体
DataBuffer dataBuffer = exchange.getResponse().bufferFactory().wrap(decryptedBody.getBytes(StandardCharsets.UTF_8));
// 创建新的请求体,作为 ServerHttpRequestDecorator 的数据源
ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return Flux.just(dataBuffer);
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
};
// 执行后续的过滤器链
return chain.filter(exchange.mutate().request(decorator).build());
});
}
@Override
public int getOrder() {
return -1;
}
}
2 返回参数加密 加密方法自己实现
package com.xhd.gateway.filter;
/**
*@Author:luyongcheng
*@Date:2024/8/27 10:51
*/
import com.xhd.common.cores.exception.ServiceException;
import com.xhd.common.cores.rsa.AesRsaUtil;
import com.xhd.common.cores.rsa.AesUtil;
import com.xhd.gateway.config.properties.EncryptProperties;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
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.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@Configuration
@Slf4j
public class ResponseEncryptFilter implements GlobalFilter, Ordered {
@Autowired
private EncryptProperties encryptProperties;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
HttpStatus statusCode = exchange.getResponse().getStatusCode();
if (Objects.equals(statusCode, HttpStatus.BAD_REQUEST) || Objects.equals(statusCode, HttpStatus.TOO_MANY_REQUESTS) || !encryptProperties.getIsEncrypt()) {
return chain.filter(exchange);
}
return modifyResponseBody(exchange, chain);
}
/**
* 修改响应体
* @param exchange
* @param chain
* @return
*/
private Mono<Void> modifyResponseBody(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse originalResponse = exchange.getResponse();
originalResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator response = buildResponse(originalResponse, bufferFactory);
return chain.filter(exchange.mutate().response(response).build());
}
@Override
public int getOrder() {
return -1;
}
private ServerHttpResponseDecorator buildResponse(ServerHttpResponse originalResponse, DataBufferFactory bufferFactory) {
return new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
DataBuffer join = dataBufferFactory.join(dataBuffers);
byte[] content = new byte[join.readableByteCount()];
join.read(content);
DataBufferUtils.release(join);
String responseData = new String(content, StandardCharsets.UTF_8);
try {
String encrypt = AesRsaUtil.encrypt(responseData, AesUtil.generateRandomKey(), encryptProperties.getPublicKeyAfter());
log.info("响应数据:" + responseData);
byte[] encryptBytes = encrypt.getBytes(StandardCharsets.UTF_8);
originalResponse.getHeaders().setContentLength(encryptBytes.length);
return bufferFactory.wrap(encryptBytes);
} catch (Exception e) {
throw new ServiceException("响应参数加密失败");
}
}));
}
return super.writeWith(body);
}
@Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return writeWith(Flux.from(body).flatMapSequential(p -> p));
}
};
}
}
完结撒花