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を書き換える.
/**
     *     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);
        }

    }