gateway对参数解密,返回值解密统一处理方法,实际验证可用
Gateway全局参数解密返回值加密:项目中前端传入参数是解密的,所以在网关处要统一对加密参数解密,在转发到对应的微服务请求参数解密统一处理:Req拦截器中处理方法:把这个方法里处理解密的Util类改成你自己的,我这里contentType约定是Json,你如果用其他的类型,自己改下MediaType.APPLICATION_JSON.:@Component@Slf4jpublic class R
·
Gateway全局参数解密返回值加密:
项目中前端传入参数是解密的,所以在网关处要统一对加密参数解密,在转发到对应的微服务
请求参数解密统一处理:
Req拦截器中处理方法:
把这个方法里处理解密的Util类改成你自己的,我这里contentType约定是Json,你如果用其他的类型,自己改下MediaType.APPLICATION_JSON.:
@Component
@Slf4j
public class ReqFilter implements GlobalFilter, Ordered {
private AntPathMatcher antPathMatcher= new AntPathMatcher();
ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers, CachedBodyOutputMessage outputMessage) {
return new ServerHttpRequestDecorator(exchange.getRequest()) {
public HttpHeaders getHeaders() {
long contentLength = headers.getContentLength();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.putAll(super.getHeaders());
if (contentLength > 0L) {
httpHeaders.setContentLength(contentLength);
} else {
httpHeaders.set("Transfer-Encoding", "chunked");
}
return httpHeaders;
}
public Flux<DataBuffer> getBody() {
return outputMessage.getBody();
}
};
}
private Mono<Void> returnMononew(GatewayFilterChain chain,ServerWebExchange exchange){
return chain.filter(exchange).then(Mono.fromRunnable(()->{
}));
}
private Mono<Void> readBody(ServerWebExchange exchange, GatewayFilterChain chain) {
//重新构造request,参考ModifyRequestBodyGatewayFilterFactory
ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
//重点
Mono<String> modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {
//因为约定了终端传参的格式,所以只考虑json的情况,如果是表单传参,请自行增加
if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType) || MediaType.APPLICATION_JSON_UTF8.isCompatibleWith(mediaType)) {
String newBody = null;
try{
// 解密body 此处调用你自己的解密方法
newBody = DecryptUtil.decipher(body);
}catch (Exception e){
e.getMessage();
}
return Mono.just(newBody);
}
return Mono.empty();
});
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
//猜测这个就是之前报400错误的元凶,之前修改了body但是没有重新写content length
headers.remove("Content-Length");
//MyCachedBodyOutputMessage 这个类完全就是CachedBodyOutputMessage,只不过CachedBodyOutputMessage不是公共的
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
ServerHttpRequest decorator = this.decorate(exchange, headers, outputMessage);
return returnMononew(chain, exchange.mutate().request(decorator).build());
}));
}
@SneakyThrows
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String path = request.getURI().getPath(); // 当前调用方法的url
HttpHeaders headers = request.getHeaders();
log.info("HttpMethod:{},Url:{}", request.getMethod(), request.getURI().getRawPath());
// 登录跳过网关验证,检查白名单(配置)最好把不拦截路径放入配置文件,此处通过正则
if(antPathMatcher.match("/**/api/login/auth/**",path)){
return readBody(exchange, chain);
}
// 处理参数
MediaType contentType = headers.getContentType();
long contentLength = headers.getContentLength();
if (contentLength > 0) {
if (MediaType.APPLICATION_JSON.equals(contentType) || MediaType.APPLICATION_JSON_UTF8.equals(contentType)) {
return readBody(exchange, chain);
}
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
返回值统一加密处理:
在我注释的地方把加密方法改成你自己的加密方式,这里已经用DataBufferFactory解决了分段响应问题
@Component
@Slf4j
public class ResFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) 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 str = new String(content, Charset.forName("UTF-8"));
log.info(str);
// 把下面加密方法改成你自己的
String encryptStr = Base64.getEncoder().encodeToString(EncryptUtil.encrypt(str));
originalResponse.getHeaders().setContentLength(encryptStr.getBytes().length);
return bufferFactory.wrap(encryptStr.getBytes());
}));
}
// if body is not a flux. never got there.
return super.writeWith(body);
}
};
// replace response with decorator
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
@Override
public int getOrder() {
return -1;
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)