一、概述
微服务项目中,各服务的对外出入口都是在网关层。
有时候,我们为了安全性考虑,会对接口返回的响应信息进行加密保护,这需要涉及到Gateway修改响应体的方法。
笔者一开始做,也踩了很多坑,在此记录一下。
二、实现方式
我们首先需要定义一个全局过滤器,拦截所有的请求。代码如下。
Gateway响应信息拦截加密
@Component
public class AuthFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 数据响应拦截(加密)
ServerHttpResponseDecorator responseDecorator = processResponse(exchange.getResponse(), exchange.getResponse().bufferFactory());
return chain.filter(exchange.mutate().response(responseDecorator).build());
}
/**
* 数据响应拦截(加密处理)
* @param serverHttpResponse 响应对象
* @param dataBufferFactory 数据Buffer工厂
* @return 返回拦截器
*/
private ServerHttpResponseDecorator processResponse(ServerHttpResponse serverHttpResponse, DataBufferFactory dataBufferFactory){
return new ServerHttpResponseDecorator(serverHttpResponse) {
@SuppressWarnings("unchecked")
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if(body instanceof Flux){
Flux<? extends DataBuffer> flux = (Flux<? extends DataBuffer>) body;
return super.writeWith(flux.buffer().map(dataBuffers -> {
StringBuilder dataBuilder = new StringBuilder();
// Gateway网关数据太长会进行分段传输
dataBuffers.forEach(dataBuffer -> {
// 数据读取
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
// 释放内存
DataBufferUtils.release(dataBuffer);
// 数据拼接
dataBuilder.append(new String(content, StandardCharsets.UTF_8));
});
// 对数据进行加密
String result = Aes.aesEncrypt(dataBuilder.toString());
// 写入数据
return dataBufferFactory.wrap(result.getBytes(StandardCharsets.UTF_8));
}));
}
return super.writeWith(body);
}
};
}
}
这里需要注意,Gateway请求返回的数据太长会进行分段传输,所以一定要等数据传输完再全部进行加密。

7582

被折叠的 条评论
为什么被折叠?



