Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
FORCE_Inc
jeecg-boot
提交
b1958fd2
J
jeecg-boot
项目概览
FORCE_Inc
/
jeecg-boot
与 Fork 源项目一致
Fork自
jeecg / jeecg-boot
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jeecg-boot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b1958fd2
编写于
6月 25, 2021
作者:
JEECG低代码平台
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
HW21-0499 表字典接口存在SQL注入漏洞,增加签名拦截器
上级
8b3d83ae
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
369 addition
and
62 deletion
+369
-62
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/config/FeignConfig.java
...cloud-api/src/main/java/org/jeecg/config/FeignConfig.java
+83
-2
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
...c/main/java/org/jeecg/common/constant/CommonConstant.java
+2
-0
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/PathMatcherUtil.java
.../src/main/java/org/jeecg/common/util/PathMatcherUtil.java
+84
-0
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java
.../jeecg/config/sign/interceptor/SignAuthConfiguration.java
+6
-7
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthInterceptor.java
...rg/jeecg/config/sign/interceptor/SignAuthInterceptor.java
+10
-21
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java
...e/src/main/java/org/jeecg/config/sign/util/HttpUtils.java
+92
-22
jeecg-boot/jeecg-boot-starter/jeecg-boot-starter-cloud/src/main/java/org/jeecg/config/FeignConfig.java
...ter-cloud/src/main/java/org/jeecg/config/FeignConfig.java
+92
-10
未找到文件。
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/config/FeignConfig.java
浏览文件 @
b1958fd2
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
<
String
,
String
>
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
<
HttpMessageConverters
>
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
<
HttpMessageConverters
>
feignHttpMessageConverter
()
{
final
HttpMessageConverters
httpMessageConverters
=
new
HttpMessageConverters
(
this
.
getFastJsonConverter
());
return
()
->
httpMessageConverters
;
}
private
FastJsonHttpMessageConverter
getFastJsonConverter
()
{
FastJsonHttpMessageConverter
converter
=
new
FastJsonHttpMessageConverter
();
List
<
MediaType
>
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 的解析支持 ----------
}
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
浏览文件 @
b1958fd2
...
...
@@ -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"
;
/**
* 多租户 请求头
...
...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/PathMatcherUtil.java
0 → 100644
浏览文件 @
b1958fd2
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
<
String
>
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
<
String
,
String
>
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
<
String
,
String
>
extractUriTemplateVariables
(
String
var1
);
}
}
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java
浏览文件 @
b1958fd2
...
...
@@ -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
);
}
}
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthInterceptor.java
浏览文件 @
b1958fd2
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
<
String
,
String
>
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<String> keySet = allParams.keySet();
// Iterator<String> 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"
);
...
...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java
浏览文件 @
b1958fd2
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
<
String
,
String
>
getAllParams
(
HttpServletRequest
request
)
throws
IOException
{
SortedMap
<
String
,
String
>
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
<
String
,
String
>
urlParams
=
getUrlParams
(
request
);
...
...
@@ -59,11 +57,45 @@ public class HttpUtils {
return
result
;
}
/**
* 将URL的参数和body参数合并
*
* @author jeecg
* @date 20210621
* @param queryString
*/
public
static
SortedMap
<
String
,
String
>
getAllParams
(
String
url
,
String
queryString
,
byte
[]
body
,
String
method
)
throws
IOException
{
SortedMap
<
String
,
String
>
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
<
String
,
String
>
urlParams
=
getUrlParams
(
queryString
);
for
(
Map
.
Entry
entry
:
urlParams
.
entrySet
())
{
result
.
put
((
String
)
entry
.
getKey
(),
(
String
)
entry
.
getValue
());
}
Map
<
String
,
String
>
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
<
String
,
String
>
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
<
String
,
String
>
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
<
String
,
String
>
getUrlParams
(
HttpServletRequest
request
)
{
Map
<
String
,
String
>
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
<
String
,
String
>
getUrlParams
(
String
queryString
)
{
Map
<
String
,
String
>
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
jeecg-boot/jeecg-boot-starter/jeecg-boot-starter-cloud/src/main/java/org/jeecg/config/FeignConfig.java
浏览文件 @
b1958fd2
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
<
String
,
String
>
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
<
HttpMessageConverters
>
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
<
HttpMessageConverters
>
feignHttpMessageConverter
()
{
final
HttpMessageConverters
httpMessageConverters
=
new
HttpMessageConverters
(
this
.
getFastJsonConverter
());
return
()
->
httpMessageConverters
;
}
private
FastJsonHttpMessageConverter
getFastJsonConverter
()
{
FastJsonHttpMessageConverter
converter
=
new
FastJsonHttpMessageConverter
();
List
<
MediaType
>
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 的解析支持 ----------
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录