Springcloud gateway filter要求パラメータの変更
最近、プロジェクトはspringcloudのgatewayをゲートウェイとして統一的な要求転送に使用し、gatewayモジュールが要求を処理してきたパラメータを復号してから後続モジュールに転送し、後続モジュールが処理してからgetway処理暗号化に戻ってフロントエンドに戻るプロセスがある.
復号化:gatewayにdecodeFilterを加え、runメソッドで処理し、復号化は主にget方式のurlパラメータおよびpost要求のようなrequestBodyのパラメータに対して処理する.
暗号化:gatewayにencodeFilterを追加しrunメソッドで暗号化操作を処理
次のコードを直接入力します.
一).復号は主にgetとpots方式に対する要求パラメータ処理である
1)get方式の処理方式で,主な論理はrequestによりパラメータ集合を取得し,集合パラメータを復号して統一的にカプセル化してget requestのqueryStringを書き換える.
復号化:gatewayにdecodeFilterを加え、runメソッドで処理し、復号化は主にget方式のurlパラメータおよびpost要求のようなrequestBodyのパラメータに対して処理する.
暗号化:gatewayにencodeFilterを追加しrunメソッドで暗号化操作を処理
次のコードを直接入力します.
一).復号は主にgetとpots方式に対する要求パラメータ処理である
1)get方式の処理方式で,主な論理はrequestによりパラメータ集合を取得し,集合パラメータを復号して統一的にカプセル化してget requestのqueryStringを書き換える.
/**
* get value aes
* @param ctx
* @throws Exception
*/
private void getAesDecrypt(RequestContext ctx) throws Exception {
HttpServletRequest request = ctx.getRequest();
Map paramMap = request.getParameterMap();
String key = getAesKey(request);
StringBuilder decryptBuilder = new StringBuilder();
for (String s : paramMap.keySet()) {
String value = paramMap.get(s)[0];
try {
log.info("key:{},......before decode value: {}",s,value);
byte[] decryptData = AESUtils.decrypt(AESUtils.parseHexStr2Byte(value), key);
decryptBuilder.append(s)
.append("=" )
.append( new String(decryptData, CommonConstants.CHARSET_UTF_8))
.append("&");
}catch (Exception e){
log.error(e.getMessage());
throw new IcarException(CommonConstants.REQUEST_CONTENT_DECRYPTION_FAILED,CommonConstants.REQUEST_CONTENT_DECRYPTION_FAILED_MESSAGE);
}
}
String decryptTemp = "";
if (StringUtils.isNotBlank(decryptBuilder.toString())) {
decryptTemp = decryptBuilder.substring(0, decryptBuilder.length() - 1); ;
}
String decryptString = decryptTemp;
refactorGetRequest(ctx,decryptString);
}
/**
* get request
* @param ctx
* @param decryptString
*/
private void refactorGetRequest(RequestContext ctx,String decryptString){
ctx.setRequest(new HttpServletRequestWrapper(ctx.getRequest()) {
@Override
public String getQueryString() {
return decryptString;
}
@Override
public String getContentType() {
return MediaType.APPLICATION_JSON_VALUE;
}
});
}
2.post方式のreuqestBodyパラメータ、主なロジックはrequestがrequestBodyを取得し、それから復号してrequestBodyを書き換える/**
* requestBody aes , post,put requestBody
* @param ctx RequestContext
* @throws Exception
*/
private void requestBodyAesDecrypt(RequestContext ctx) throws Exception {
HttpServletRequest request = ctx.getRequest();
ServletInputStream servletInputStream = request.getInputStream();
String requestParam = StreamUtils
.copyToString(servletInputStream, Charset.forName(CommonConstants.CHARSET_UTF_8));
String key = getAesKey(request);
byte[] decryptData = new byte[]{};
if(StringUtils.isNotBlank(requestParam)){
try {
log.info("before decode :{}",requestParam);
decryptData = AESUtils.decrypt(AESUtils.parseHexStr2Byte(requestParam), key);
}catch (Exception e){
log.error(e.getMessage());
throw new IcarException(CommonConstants.REQUEST_CONTENT_DECRYPTION_FAILED,CommonConstants.REQUEST_CONTENT_DECRYPTION_FAILED_MESSAGE);
}
}
refactorPostRequest(ctx,decryptData);
}
/**
* post request
* @param ctx
* @param decryptData
*/
private void refactorPostRequest(RequestContext ctx, byte[] decryptData){
// request content-type json ctx.addZuulRequestHeader(HeaderCode.CONTENT_TPPE,MediaType.APPLICATION_JSON_VALUE);
ctx.setRequest(new HttpServletRequestWrapper(ctx.getRequest()) {
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamWrapper(decryptData);
}
@Override
public int getContentLength() {
return decryptData.length;
}
@Override
public long getContentLengthLong() {
return decryptData.length;
}
});
}
二).暗号化操作/**
* body aes
*/
private void aesEncode(RequestContext ctx) throws Exception {
try {
InputStream inputStream = ctx.getResponseDataStream();
String response = StreamUtils.copyToString(inputStream, Charset.forName(CommonConstants.CHARSET_UTF_8));
//aes
log.info("before aes encode response: {}", response);
HttpServletRequest request = ctx.getRequest();
String key = getAesKey(request);
byte[] encodeResult = AESUtils.encrypt(response.getBytes(), key);
String result = AESUtils.parseByte2HexStr(encodeResult);
log.info("aes encode result ={}", result);
ctx.setResponseBody(result);
} catch (Exception e) {
log.error(e.getMessage());
throw new IcarException(CommonConstants.AES_ENCODE_FAILED, CommonConstants.AES_ENCODE_FAILED_MESSAGE);
}
}