From b1958fd295286de768ebba4498ef0f5223e9e8a8 Mon Sep 17 00:00:00 2001 From: zhangdaiscott Date: Fri, 25 Jun 2021 11:50:34 +0800 Subject: [PATCH] =?UTF-8?q?HW21-0499=20=E8=A1=A8=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AD=98=E5=9C=A8SQL=E6=B3=A8=E5=85=A5?= =?UTF-8?q?=E6=BC=8F=E6=B4=9E=EF=BC=8C=E5=A2=9E=E5=8A=A0=E7=AD=BE=E5=90=8D?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/jeecg/config/FeignConfig.java | 85 ++++++++++++- .../jeecg/common/constant/CommonConstant.java | 2 + .../jeecg/common/util/PathMatcherUtil.java | 84 +++++++++++++ .../interceptor/SignAuthConfiguration.java | 13 +- .../sign/interceptor/SignAuthInterceptor.java | 31 ++--- .../org/jeecg/config/sign/util/HttpUtils.java | 114 ++++++++++++++---- .../java/org/jeecg/config/FeignConfig.java | 102 ++++++++++++++-- 7 files changed, 369 insertions(+), 62 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/PathMatcherUtil.java diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/config/FeignConfig.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/config/FeignConfig.java index 63207d0..a0572cd 100644 --- a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/config/FeignConfig.java +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/config/FeignConfig.java @@ -1,26 +1,44 @@ package org.jeecg.config; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer; import feign.Feign; import feign.Logger; import feign.RequestInterceptor; +import feign.codec.Decoder; import feign.codec.Encoder; import feign.form.spring.SpringFormEncoder; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.util.DateUtils; +import org.jeecg.common.util.PathMatcherUtil; +import org.jeecg.config.sign.interceptor.SignAuthConfiguration; +import org.jeecg.config.sign.util.HttpUtils; +import org.jeecg.config.sign.util.SignUtil; import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.FeignAutoConfiguration; +import org.springframework.cloud.openfeign.support.SpringDecoder; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Scope; +import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.SortedMap; @ConditionalOnClass(Feign.class) @AutoConfigureBefore(FeignAutoConfiguration.class) @@ -37,11 +55,36 @@ public class FeignConfig { log.info("Feign request: {}", request.getRequestURI()); // 将token信息放入header中 String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); - if(token==null){ + if(token==null || "".equals(token)){ token = request.getParameter("token"); } log.info("Feign request token: {}", token); requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token); + + //根据URL地址过滤请求 【字典表参数签名验证】 + if (PathMatcherUtil.matches(Arrays.asList(SignAuthConfiguration.urlList),requestTemplate.path())) { + try { + log.info("============================ [begin] fegin api url ============================"); + log.info(requestTemplate.path()); + log.info(requestTemplate.method()); + String queryLine = requestTemplate.queryLine(); + if(queryLine!=null && queryLine.startsWith("?")){ + queryLine = queryLine.substring(1); + } + log.info(queryLine); + if(requestTemplate.body()!=null){ + log.info(new String(requestTemplate.body())); + } + SortedMap allParams = HttpUtils.getAllParams(requestTemplate.path(),queryLine,requestTemplate.body(),requestTemplate.method()); + String sign = SignUtil.getParamsSign(allParams); + log.info(" Feign request params sign: {}",sign); + log.info("============================ [end] fegin api url ============================"); + requestTemplate.header(CommonConstant.X_SIGN, sign); + requestTemplate.header(CommonConstant.X_TIMESTAMP, DateUtils.getCurrentTimestamp().toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } } }; } @@ -72,4 +115,42 @@ public class FeignConfig { public Encoder multipartFormEncoder(ObjectFactory messageConverters) { return new SpringFormEncoder(new SpringEncoder(messageConverters)); } + + // update-begin--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ---------- + @Bean + public Encoder feignEncoder() { + return new SpringEncoder(feignHttpMessageConverter()); + } + + @Bean + public Decoder feignDecoder() { + return new SpringDecoder(feignHttpMessageConverter()); + } + + /** + * 设置解码器为fastjson + * + * @return + */ + private ObjectFactory feignHttpMessageConverter() { + final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(this.getFastJsonConverter()); + return () -> httpMessageConverters; + } + + private FastJsonHttpMessageConverter getFastJsonConverter() { + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + + List supportedMediaTypes = new ArrayList<>(); + MediaType mediaTypeJson = MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE); + supportedMediaTypes.add(mediaTypeJson); + converter.setSupportedMediaTypes(supportedMediaTypes); + FastJsonConfig config = new FastJsonConfig(); + config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer()); + config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); + converter.setFastJsonConfig(config); + + return converter; + } + // update-end--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ---------- + } diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java index ce8d889..0175d0f 100644 --- a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java @@ -290,6 +290,8 @@ public interface CommonConstant { public final static String X_ACCESS_TOKEN = "X-Access-Token"; + public final static String X_SIGN = "X-Sign"; + public final static String X_TIMESTAMP = "X-TIMESTAMP"; /** * 多租户 请求头 diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/PathMatcherUtil.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/PathMatcherUtil.java new file mode 100644 index 0000000..0b813f4 --- /dev/null +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/PathMatcherUtil.java @@ -0,0 +1,84 @@ +package org.jeecg.common.util; + +import org.springframework.util.AntPathMatcher; + +import java.util.Collection; +import java.util.Map; + +/** + * 使用Spring自身提供的地址匹配工具匹配URL + */ +public class PathMatcherUtil { + + public static void main(String[] args) { + String url = "/sys/dict/loadDictOrderByValue/tree,s2,2"; + String p = "/sys/dict/loadDictOrderByValue/*"; + + System.out.println(PathMatcherUtil.match(p,url)); + } + + /** + * 实际验证路径匹配权限 + * + * @param matchPath 权限url + * @param path 访问路径 + * @return 是否拥有权限 + */ + public static boolean match(String matchPath, String path) { + SpringAntMatcher springAntMatcher = new SpringAntMatcher(matchPath, true); + return springAntMatcher.matches(path); + } + + /** + * 实际验证路径匹配权限 + * + * @param list 权限url + * @param path 访问路径 + * @return 是否拥有权限 + */ + public static boolean matches(Collection list, String path) { + for (String s : list) { + SpringAntMatcher springAntMatcher = new SpringAntMatcher(s, true); + if (springAntMatcher.matches(path)) { + return true; + } + } + return false; + } + + /** + * 地址表达式匹配工具 + */ + private static class SpringAntMatcher implements Matcher { + private final AntPathMatcher antMatcher; + private final String pattern; + + private SpringAntMatcher(String pattern, boolean caseSensitive) { + this.pattern = pattern; + this.antMatcher = createMatcher(caseSensitive); + } + + @Override + public boolean matches(String path) { + return this.antMatcher.match(this.pattern, path); + } + + @Override + public Map extractUriTemplateVariables(String path) { + return this.antMatcher.extractUriTemplateVariables(this.pattern, path); + } + + private static AntPathMatcher createMatcher(boolean caseSensitive) { + AntPathMatcher matcher = new AntPathMatcher(); + matcher.setTrimTokens(false); + matcher.setCaseSensitive(caseSensitive); + return matcher; + } + } + + private interface Matcher { + boolean matches(String var1); + + Map extractUriTemplateVariables(String var1); + } +} diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java index 0414af2..aa231b1 100644 --- a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java @@ -6,11 +6,14 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** - * online 拦截器配置 + * 签名 拦截器配置 */ @Configuration public class SignAuthConfiguration implements WebMvcConfigurer { - + public static String[] urlList = new String[] {"/sys/dict/getDictItems/*", "/sys/dict/loadDict/*", + "/sys/dict/loadDictOrderByValue/*", "/sys/dict/loadDictItem/*", "/sys/dict/loadTreeData", + "/sys/api/queryTableDictItemsByCode", "/sys/api/queryFilterTableDictInfo", "/sys/api/queryTableDictByKeys", + "/sys/api/translateDictFromTable", "/sys/api/translateDictFromTableByKeys"}; @Bean public SignAuthInterceptor signAuthInterceptor() { return new SignAuthInterceptor(); @@ -18,10 +21,6 @@ public class SignAuthConfiguration implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { - String[] inculudes = new String[] {"/sys/dict/getDictItems/*", "/sys/dict/loadDict/*", - "/sys/dict/loadDictOrderByValue/*", "/sys/dict/loadDictItem/*", "/sys/dict/loadTreeData", - "/sys/api/queryTableDictItemsByCode", "/sys/api/queryFilterTableDictInfo", "/sys/api/queryTableDictByKeys", - "/sys/api/translateDictFromTable", "/sys/api/translateDictFromTableByKeys"}; - registry.addInterceptor(signAuthInterceptor()).addPathPatterns(inculudes); + registry.addInterceptor(signAuthInterceptor()).addPathPatterns(urlList); } } diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthInterceptor.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthInterceptor.java index 4dcfa2c..8ca0e9b 100644 --- a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthInterceptor.java +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthInterceptor.java @@ -1,22 +1,20 @@ package org.jeecg.config.sign.interceptor; -import java.io.PrintWriter; -import java.util.SortedMap; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.util.DateUtils; import org.jeecg.config.sign.util.BodyReaderHttpServletRequestWrapper; import org.jeecg.config.sign.util.HttpUtils; import org.jeecg.config.sign.util.SignUtil; import org.springframework.web.servlet.HandlerInterceptor; -import com.alibaba.fastjson.JSON; - -import lombok.extern.slf4j.Slf4j; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; +import java.util.SortedMap; /** * 签名拦截器 @@ -31,13 +29,13 @@ public class SignAuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - log.debug("request URI = " + request.getRequestURI()); + log.info("request URI = " + request.getRequestURI()); HttpServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request); //获取全部参数(包括URL和body上的) SortedMap allParams = HttpUtils.getAllParams(requestWrapper); //对参数进行签名验证 - String headerSign = request.getHeader("X-Sign"); - String timesTamp = request.getHeader("X-TIMESTAMP"); + String headerSign = request.getHeader(CommonConstant.X_SIGN); + String timesTamp = request.getHeader(CommonConstant.X_TIMESTAMP); //1.校验时间有消息 try { @@ -60,15 +58,6 @@ public class SignAuthInterceptor implements HandlerInterceptor { } else { log.error("request URI = " + request.getRequestURI()); log.error("Sign 签名校验失败!Header Sign : {}",headerSign); -// //打印日志参数 -// Set keySet = allParams.keySet(); -// Iterator paramIt = keySet.iterator(); -// while(paramIt.hasNext()){ -// String pkey = paramIt.next(); -// String pval = allParams.get(pkey); -// log.error(" ["+pkey+":"+pval+"] "); -// } - //校验失败返回前端 response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java index 9e51bae..5a56339 100644 --- a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java @@ -1,5 +1,10 @@ package org.jeecg.config.sign.util; +import com.alibaba.fastjson.JSONObject; +import org.jeecg.common.util.oConvertUtils; +import org.springframework.http.HttpMethod; + +import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -10,35 +15,28 @@ import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; -import javax.servlet.http.HttpServletRequest; - -import org.jeecg.common.util.oConvertUtils; -import org.springframework.http.HttpMethod; - -import com.alibaba.fastjson.JSONObject; - /** * http 工具类 获取请求中的参数 - * - * @author show - * @date 14:23 2019/5/29 + * + * @author jeecg + * @date 20210621 */ public class HttpUtils { /** * 将URL的参数和body参数合并 - * - * @author show - * @date 14:24 2019/5/29 + * + * @author jeecg + * @date 20210621 * @param request */ public static SortedMap getAllParams(HttpServletRequest request) throws IOException { SortedMap result = new TreeMap<>(); // 获取URL上最后带逗号的参数变量 sys/dict/getDictItems/sys_user,realname,username - String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/")+1); - if(pathVariable.contains(",")){ - result.put(SignUtil.xPathVariable,pathVariable); + String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1); + if (pathVariable.contains(",")) { + result.put(SignUtil.xPathVariable, pathVariable); } // 获取URL上的参数 Map urlParams = getUrlParams(request); @@ -59,11 +57,45 @@ public class HttpUtils { return result; } + /** + * 将URL的参数和body参数合并 + * + * @author jeecg + * @date 20210621 + * @param queryString + */ + public static SortedMap getAllParams(String url, String queryString, byte[] body, String method) + throws IOException { + + SortedMap result = new TreeMap<>(); + // 获取URL上最后带逗号的参数变量 sys/dict/getDictItems/sys_user,realname,username + String pathVariable = url.substring(url.lastIndexOf("/") + 1); + if (pathVariable.contains(",")) { + result.put(SignUtil.xPathVariable, pathVariable); + } + // 获取URL上的参数 + Map urlParams = getUrlParams(queryString); + for (Map.Entry entry : urlParams.entrySet()) { + result.put((String)entry.getKey(), (String)entry.getValue()); + } + Map allRequestParam = new HashMap<>(16); + // get请求不需要拿body参数 + if (!HttpMethod.GET.name().equals(method)) { + allRequestParam = getAllRequestParam(body); + } + // 将URL的参数和body参数进行合并 + if (allRequestParam != null) { + for (Map.Entry entry : allRequestParam.entrySet()) { + result.put((String)entry.getKey(), (String)entry.getValue()); + } + } + return result; + } + /** * 获取 Body 参数 - * - * @author show - * @date 15:04 2019/5/30 + * + * @date 15:04 20210621 * @param request */ public static Map getAllRequestParam(final HttpServletRequest request) throws IOException { @@ -79,15 +111,29 @@ public class HttpUtils { return JSONObject.parseObject(wholeStr.toString(), Map.class); } + /** + * 获取 Body 参数 + * + * @date 15:04 20210621 + * @param body + */ + public static Map getAllRequestParam(final byte[] body) throws IOException { + if(body==null){ + return null; + } + String wholeStr = new String(body); + // 转化成json对象 + return JSONObject.parseObject(wholeStr.toString(), Map.class); + } + /** * 将URL请求参数转换成Map - * - * @author show + * * @param request */ public static Map getUrlParams(HttpServletRequest request) { Map result = new HashMap<>(16); - if(oConvertUtils.isEmpty(request.getQueryString())){ + if (oConvertUtils.isEmpty(request.getQueryString())) { return result; } String param = ""; @@ -103,4 +149,28 @@ public class HttpUtils { } return result; } + + /** + * 将URL请求参数转换成Map + * + * @param queryString + */ + public static Map getUrlParams(String queryString) { + Map result = new HashMap<>(16); + if (oConvertUtils.isEmpty(queryString)) { + return result; + } + String param = ""; + try { + param = URLDecoder.decode(queryString, "utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + String[] params = param.split("&"); + for (String s : params) { + int index = s.indexOf("="); + result.put(s.substring(0, index), s.substring(index + 1)); + } + return result; + } } \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-starter/jeecg-boot-starter-cloud/src/main/java/org/jeecg/config/FeignConfig.java b/jeecg-boot/jeecg-boot-starter/jeecg-boot-starter-cloud/src/main/java/org/jeecg/config/FeignConfig.java index f19ea5f..3cc2b47 100644 --- a/jeecg-boot/jeecg-boot-starter/jeecg-boot-starter-cloud/src/main/java/org/jeecg/config/FeignConfig.java +++ b/jeecg-boot/jeecg-boot-starter/jeecg-boot-starter-cloud/src/main/java/org/jeecg/config/FeignConfig.java @@ -1,28 +1,47 @@ package org.jeecg.config; -import feign.Feign; -import feign.Logger; -import feign.RequestInterceptor; -import feign.codec.Encoder; -import feign.form.spring.SpringFormEncoder; -import lombok.extern.slf4j.Slf4j; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.SortedMap; + +import javax.servlet.http.HttpServletRequest; + import org.jeecg.common.constant.CommonConstant; -import org.jeecg.config.FeignConfig; +import org.jeecg.common.util.DateUtils; +import org.jeecg.common.util.PathMatcherUtil; +import org.jeecg.config.sign.interceptor.SignAuthConfiguration; +import org.jeecg.config.sign.util.HttpUtils; +import org.jeecg.config.sign.util.SignUtil; import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.FeignAutoConfiguration; +import org.springframework.cloud.openfeign.support.SpringDecoder; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Scope; +import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import javax.servlet.http.HttpServletRequest; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer; + +import feign.Feign; +import feign.Logger; +import feign.RequestInterceptor; +import feign.codec.Decoder; +import feign.codec.Encoder; +import feign.form.spring.SpringFormEncoder; +import lombok.extern.slf4j.Slf4j; @ConditionalOnClass(Feign.class) @AutoConfigureBefore(FeignAutoConfiguration.class) @@ -39,11 +58,36 @@ public class FeignConfig { log.info("Feign request: {}", request.getRequestURI()); // 将token信息放入header中 String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); - if(token==null){ + if(token==null || "".equals(token)){ token = request.getParameter("token"); } log.info("Feign request token: {}", token); requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token); + + //根据URL地址过滤请求 【字典表参数签名验证】 + if (PathMatcherUtil.matches(Arrays.asList(SignAuthConfiguration.urlList),requestTemplate.path())) { + try { + log.info("============================ [begin] fegin starter url ============================"); + log.info(requestTemplate.path()); + log.info(requestTemplate.method()); + String queryLine = requestTemplate.queryLine(); + if(queryLine!=null && queryLine.startsWith("?")){ + queryLine = queryLine.substring(1); + } + log.info(queryLine); + if(requestTemplate.body()!=null){ + log.info(new String(requestTemplate.body())); + } + SortedMap allParams = HttpUtils.getAllParams(requestTemplate.path(),queryLine,requestTemplate.body(),requestTemplate.method()); + String sign = SignUtil.getParamsSign(allParams); + log.info(" Feign request params sign: {}",sign); + log.info("============================ [end] fegin starter url ============================"); + requestTemplate.header(CommonConstant.X_SIGN, sign); + requestTemplate.header(CommonConstant.X_TIMESTAMP, DateUtils.getCurrentTimestamp().toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } } }; } @@ -74,4 +118,42 @@ public class FeignConfig { public Encoder multipartFormEncoder(ObjectFactory messageConverters) { return new SpringFormEncoder(new SpringEncoder(messageConverters)); } + + // update-begin--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ---------- + @Bean + public Encoder feignEncoder() { + return new SpringEncoder(feignHttpMessageConverter()); + } + + @Bean + public Decoder feignDecoder() { + return new SpringDecoder(feignHttpMessageConverter()); + } + + /** + * 设置解码器为fastjson + * + * @return + */ + private ObjectFactory feignHttpMessageConverter() { + final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(this.getFastJsonConverter()); + return () -> httpMessageConverters; + } + + private FastJsonHttpMessageConverter getFastJsonConverter() { + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + + List supportedMediaTypes = new ArrayList<>(); + MediaType mediaTypeJson = MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE); + supportedMediaTypes.add(mediaTypeJson); + converter.setSupportedMediaTypes(supportedMediaTypes); + FastJsonConfig config = new FastJsonConfig(); + config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer()); + config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); + converter.setFastJsonConfig(config); + + return converter; + } + // update-end--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ---------- + } -- GitLab