Spring Cloud Gateway 响应数据加密

Spring Cloud Gateway实现了请求的解密和响应的加密,‌主要使用的是Hutool工具类中的AES加密算法。‌这种加密方式不仅用于请求数据的解密,‌还用于响应数据的加密。‌通过在网关中添加过滤器GlobalFilter,‌可以实现这一功能。‌具体来说,‌Spring Cloud Gateway的加密和解密流程包括以下几个步骤:‌

  1. 前端获取RSA公钥:‌首先,‌前端客户端通过访问一个特定的接口从服务器获取RSA公钥。‌
  2. 对称密钥加密:‌客户端生成一个随机的对称密钥,‌然后使用服务器的RSA公钥对这个对称密钥进行加密。‌
  3. 发送加密的对称密钥:‌客户端将加密后的对称密钥发送到服务器。‌
  4. 对称密钥解密:‌服务器使用自己的RSA私钥解密客户端发送的加密对称密钥,‌从而得到原始的对称密钥。‌
  5. 加密通信:‌从这一步开始,‌客户端和服务器都会使用这个对称密钥来加密和解密他们之间的通信。‌这包括URL的动态加密、‌请求和响应的加密解密,‌以及数字签名的验证等。‌
  6. 响应数据加密:‌在响应数据发送回客户端之前,‌使用相同的对称密钥对响应数据进行加密,‌确保数据在传输过程中的安全性。‌

通过这种方式,‌Spring Cloud Gateway确保了客户端和服务器之间的通信安全,‌防止数据被截获或篡改,‌同时也提供了一个有效的机制来验证通信双方的身份。

AES方法:CSDN

Gateway响应数据加密:如下,只有返回数据为json才加密,对于下载还是返回的流这些都不做处理加密;

package com.puwang.springcloud.gateway.filter;

import com.google.common.base.Charsets;
import com.puwang.springcloud.gateway.util.AESUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
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.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Objects;

@Slf4j
@Component
public class EncryptResponseFilter implements GlobalFilter, Ordered {

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		URI uri = exchange.getRequest().getURI();
		log.info("URI的参数 "+uri.toString());
		log.info("============================Return data encryption============================");
		HttpStatus statusCode = exchange.getResponse().getStatusCode();
		if(Objects.equals(statusCode, HttpStatus.BAD_REQUEST)
				|| Objects.equals(statusCode, HttpStatus.TOO_MANY_REQUESTS)
				||uri.getPath().contains(unCheckUrl) ||uri.getPath().contains(randomUrl)
				||uri.getPath().contains(fileDownLoad) ||uri.getPath().contains(LOGIN_BUTT) ||uri.getPath().contains(ISC_SSO_LOGIN)){
			// 如果是特殊的请求,已处理响应内容,这里不再处理
			return chain.filter(exchange);
		}

		// 根据具体业务内容,修改响应体
		ServerHttpResponse originalResponse = exchange.getResponse();
		HttpHeaders headers = originalResponse.getHeaders();
		DataBufferFactory bufferFactory = originalResponse.bufferFactory();
		ServerHttpResponseDecorator responseDecorator = 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);
						String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
						System.err.println(contentType); //
						if (contentType.contains("application/json")){
							byte[] content = new byte[join.readableByteCount()];
							join.read(content);
							DataBufferUtils.release(join);
							// 流转为字符串
							String responseData = new String(content, Charsets.UTF_8);
							if(Strings.isNotBlank(responseData)){
								responseData = AESUtil.encrypt(responseData);
							}
							byte[] uppedContent = responseData.getBytes(Charsets.UTF_8);
							originalResponse.getHeaders().setContentLength(uppedContent.length);
							return bufferFactory.wrap(uppedContent);
						}
						return join;
					}));
				} else {
					log.error("获取响应体数据 :"+getStatusCode());
				}
				return super.writeWith(body);
			}

			@Override
			public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
				return writeWith(Flux.from(body).flatMapSequential(p -> p));
			}
		};
		return chain.filter(exchange.mutate().response(responseDecorator).build());
	}

	@Override
	public int getOrder() {
		return -200;
	}


}

喜欢的朋友点个赞,加个收藏吧

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway中,可以使用AES加密算法进行加密。AES(Advanced Encryption Standard)是一种对称加密算法,它可以对数据进行加密和解密。在网关中,可以使用AES算法对请求和响应数据进行加密和解密,以保护数据的安全性。 使用AES加密算法需要以下步骤: 1. 生成AES密钥:首先需要生成一个AES密钥,可以使用随机数生成器生成一个密钥。 2. 加密数据:将需要加密数据使用生成的AES密钥进行加密,可以使用AES算法提供的加密函数进行操作。 3. 解密数据:将加密后的数据使用相同的AES密钥进行解密,可以使用AES算法提供的解密函数进行操作。 在Spring Cloud Gateway中,可以通过自定义过滤器实现AES加密和解密的功能。可以在请求到达网关时,使用过滤器对请求数据进行加密,然后将加密后的数据发送到后端服务。在响应返回时,再使用过滤器响应数据进行解密,然后将解密后的数据返回给客户端。 需要注意的是,AES加密算法是对称加密算法,加密和解密使用相同的密钥。因此,在网关和后端服务之间需要共享同一个AES密钥,以确保数据的正确加密和解密。 参考文献: \[1\] 加密验密. https://www.jianshu.com/p/7e6e6b1e7b7e \[2\] spring cloud. https://www.jianshu.com/p/7e6e6b1e7b7e \[3\] 小程序公网访问. https://www.jianshu.com/p/7e6e6b1e7b7e #### 引用[.reference_title] - *1* *2* *3* [spring cloud gateway 实现基于非服务发现的应用报文签名&加密&路由](https://blog.csdn.net/dreamsigel/article/details/106540231)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值