Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wecloud_im_server
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hewei
wecloud_im_server
Commits
07ffd8ee
Commit
07ffd8ee
authored
Apr 14, 2022
by
罗长华
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
删除现有签名类
parent
2fddcc3c
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
0 additions
and
910 deletions
+0
-910
framework/src/main/java/io/geekidea/springbootplus/framework/signature/ControllerValidatorAspect.java
+0
-273
framework/src/main/java/io/geekidea/springbootplus/framework/signature/Signature.java
+0
-34
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureException.java
+0
-24
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureField.java
+0
-29
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureHeaders.java
+0
-77
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureProperties.java
+0
-39
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureUtils.java
+0
-361
framework/src/main/java/io/geekidea/springbootplus/framework/signature/ValidatorUtils.java
+0
-73
No files found.
framework/src/main/java/io/geekidea/springbootplus/framework/signature/ControllerValidatorAspect.java
deleted
100644 → 0
View file @
2fddcc3c
package
io
.
geekidea
.
springbootplus
.
framework
.
signature
;
import
lombok.extern.slf4j.Slf4j
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Method
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.Optional
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
import
javax.servlet.http.HttpServletRequest
;
import
org.apache.commons.lang3.StringUtils
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.context.properties.bind.Bindable
;
import
org.springframework.boot.context.properties.bind.Binder
;
import
org.springframework.boot.context.properties.source.ConfigurationPropertySource
;
import
org.springframework.boot.context.properties.source.MapConfigurationPropertySource
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Component
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.web.bind.annotation.ModelAttribute
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
com.google.common.collect.Lists
;
/**
* 签名拦截器
* @Author linux
* @Date 2021年01月20日 04:21:30
* @Version 1.0
*/
//@Order(2)
//@Aspect
//@Component
@Slf4j
public
class
ControllerValidatorAspect
implements
InitializingBean
{
private
static
final
String
REQUEST_URL_OPEN
=
"request-url-open"
;
/**
* 同一个请求多长时间内有效
*/
@Value
(
"${signature.expireTime:600000}"
)
private
Long
expireTime
;
/**
* 同一个nonce 请求多长时间内不允许重复请求
*/
@Value
(
"${signature.resubmitDuration:60000}"
)
private
Long
resubmitDuration
;
/**
* appSecret
*/
@Value
(
"${signature.appSecret}"
)
private
String
appSecret
;
@Autowired
private
RedisTemplate
<
Object
,
Object
>
redisTemplate
;
@Around
(
"@annotation(io.geekidea.springbootplus.framework.signature.Signature) "
+
"&& (@annotation(org.springframework.web.bind.annotation.RequestMapping) "
+
"|| @annotation(org.springframework.web.bind.annotation.GetMapping) "
+
"|| @annotation(org.springframework.web.bind.annotation.PostMapping) "
+
"|| @annotation(org.springframework.web.bind.annotation.DeleteMapping) "
+
"|| @annotation(org.springframework.web.bind.annotation.PatchMapping))"
)
public
Object
doAround
(
ProceedingJoinPoint
pjp
)
throws
Throwable
{
//NOSONAR
HttpServletRequest
request
=
((
ServletRequestAttributes
)
(
RequestContextHolder
.
currentRequestAttributes
())).
getRequest
();
//如果不是开放的URL, 进行签名校验
if
(
Objects
.
isNull
(
request
.
getHeader
(
REQUEST_URL_OPEN
)))
{
MethodSignature
methodSignature
=
(
MethodSignature
)
pjp
.
getSignature
();
Method
method
=
methodSignature
.
getMethod
();
Signature
signature
=
AnnotationUtils
.
findAnnotation
(
method
,
Signature
.
class
);
//获取header中的相关参数
SignatureHeaders
signatureHeaders
=
generateSignatureHeaders
(
signature
,
request
);
//客户端签名
String
clientSignature
=
signatureHeaders
.
getSignature
();
//获取到header中的拼接结果
String
headersToSplice
=
SignatureUtils
.
toSplice
(
signatureHeaders
);
//服务端签名
List
<
String
>
allSplice
=
generateAllSplice
(
method
,
pjp
.
getArgs
(),
headersToSplice
);
String
serverSignature
=
SignatureUtils
.
signature
(
allSplice
.
toArray
(
new
String
[]{}),
signatureHeaders
.
getAppsecret
());
if
(!
clientSignature
.
equals
(
serverSignature
))
{
if
(
log
.
isErrorEnabled
())
{
log
.
error
(
String
.
format
(
"签名不一致... clientSignature=%s, serverSignature=%s"
,
clientSignature
,
serverSignature
));
}
throw
new
SignatureException
(
"signature error"
);
}
// SignatureContext.setSignatureHeaders(signatureHeaders);
log
.
info
(
"签名验证通过, 相关信息: "
+
signatureHeaders
);
}
try
{
return
pjp
.
proceed
();
}
catch
(
Throwable
e
)
{
//NOSONAR
throw
e
;
}
}
/**
* 根据request 中 header值生成SignatureHeaders实体
* @Author linux
* @Date 2021年02月07日 10:50:14
* @param signature
* @param request
* @Return
*/
private
SignatureHeaders
generateSignatureHeaders
(
Signature
signature
,
HttpServletRequest
request
)
throws
Exception
{
//NOSONAR
// 筛选头信息
Map
<
String
,
Object
>
headerMap
=
Collections
.
list
(
request
.
getHeaderNames
())
.
stream
()
.
filter
(
SignatureHeaders
.
SIGNATURE_HEADER_SET
::
contains
)
.
collect
(
Collectors
.
toMap
(
headerName
->
headerName
.
replaceAll
(
"-"
,
"."
),
request:
:
getHeader
));
// 自定义ConfigurationProperty源信息
ConfigurationPropertySource
sources
=
new
MapConfigurationPropertySource
(
headerMap
);
// 创建Binder绑定类
Binder
binder
=
new
Binder
(
sources
);
// 绑定属性
SignatureHeaders
signatureHeaders
=
binder
.
bind
(
"can.signature"
,
Bindable
.
of
(
SignatureHeaders
.
class
)).
get
();
// 检验参数合法性
Optional
<
String
>
result
=
ValidatorUtils
.
validateAll
(
signatureHeaders
);
if
(
result
.
isPresent
()
&&
StringUtils
.
isNotBlank
(
result
.
get
()))
{
throw
new
SignatureException
(
"WMH5000"
,
result
.
get
());
}
if
(
StringUtils
.
isBlank
(
appSecret
))
{
log
.
error
(
"未设置app secret"
);
throw
new
SignatureException
(
"WMH5002"
);
}
//其他合法性校验
Long
now
=
System
.
currentTimeMillis
();
Long
requestTimestamp
=
Long
.
parseLong
(
signatureHeaders
.
getTimestamp
());
if
((
now
-
requestTimestamp
)
>
expireTime
)
{
String
errMsg
=
"请求时间超过规定范围时间, signature="
+
signatureHeaders
.
getSignature
();
if
(
log
.
isErrorEnabled
())
{
log
.
error
(
errMsg
);
}
throw
new
SignatureException
(
"WMH5000"
,
errMsg
);
}
String
nonce
=
signatureHeaders
.
getNonce
();
if
(
nonce
.
length
()
<
10
)
{
String
errMsg
=
"6, nonce="
+
nonce
;
log
.
error
(
errMsg
);
throw
new
SignatureException
(
"WMH5000"
,
errMsg
);
}
if
(!
signature
.
resubmit
())
{
String
existNonce
=
redisTemplate
.
opsForValue
().
get
(
nonce
).
toString
();
if
(
StringUtils
.
isBlank
(
existNonce
))
{
redisTemplate
.
opsForValue
().
set
(
nonce
,
nonce
);
redisTemplate
.
expire
(
nonce
,
(
int
)
TimeUnit
.
MILLISECONDS
.
toSeconds
(
resubmitDuration
),
TimeUnit
.
SECONDS
);
}
else
{
String
errMsg
=
"不允许重复请求, nonce="
+
nonce
;
log
.
error
(
errMsg
);
throw
new
SignatureException
(
"WMH5000"
,
errMsg
);
}
}
signatureHeaders
.
setAppsecret
(
appSecret
);
return
signatureHeaders
;
}
/**
* 生成header中的参数,mehtod中的参数的拼接
* @Author linux
* @Date 2021年02月07日 10:53:18
* @param method
* @param args
* @param headersToSplice
* @Return
*/
private
List
<
String
>
generateAllSplice
(
Method
method
,
Object
[]
args
,
String
headersToSplice
)
{
List
<
String
>
pathVariables
=
Lists
.
newArrayList
();
List
<
String
>
requestParams
=
Lists
.
newArrayList
();
String
beanParams
=
StringUtils
.
EMPTY
;
for
(
int
i
=
0
;
i
<
method
.
getParameterCount
();
++
i
)
{
MethodParameter
mp
=
new
MethodParameter
(
method
,
i
);
boolean
findSignature
=
false
;
for
(
Annotation
anno
:
mp
.
getParameterAnnotations
())
{
if
(
anno
instanceof
PathVariable
)
{
if
(!
Objects
.
isNull
(
args
[
i
]))
{
pathVariables
.
add
(
args
[
i
].
toString
());
}
findSignature
=
true
;
}
else
if
(
anno
instanceof
RequestParam
)
{
RequestParam
rp
=
(
RequestParam
)
anno
;
String
name
=
mp
.
getParameterName
();
if
(
StringUtils
.
isNotBlank
(
rp
.
name
()))
{
name
=
rp
.
name
();
}
if
(!
Objects
.
isNull
(
args
[
i
]))
{
List
<
String
>
values
=
Lists
.
newArrayList
();
if
(
args
[
i
].
getClass
().
isArray
())
{
//数组
for
(
int
j
=
0
;
j
<
Array
.
getLength
(
args
[
i
]);
++
j
)
{
values
.
add
(
Array
.
get
(
args
[
i
],
j
).
toString
());
}
}
else
if
(
ClassUtils
.
isAssignable
(
Collection
.
class
,
args
[
i
].
getClass
()))
{
//集合
for
(
Object
o
:
(
Collection
<?>)
args
[
i
])
{
values
.
add
(
o
.
toString
());
}
}
else
{
//单个值
values
.
add
(
args
[
i
].
toString
());
}
values
.
sort
(
Comparator
.
naturalOrder
());
requestParams
.
add
(
name
+
"="
+
StringUtils
.
join
(
values
));
}
findSignature
=
true
;
}
else
if
(
anno
instanceof
RequestBody
||
anno
instanceof
ModelAttribute
)
{
beanParams
=
SignatureUtils
.
toSplice
(
args
[
i
]);
findSignature
=
true
;
}
if
(
findSignature
)
{
break
;
}
}
if
(!
findSignature
)
{
log
.
info
(
String
.
format
(
"签名未识别的注解, method=%s, parameter=%s, annotations=%s"
,
method
.
getName
(),
mp
.
getParameterName
(),
StringUtils
.
join
(
mp
.
getMethodAnnotations
())));
}
}
List
<
String
>
toSplices
=
Lists
.
newArrayList
();
toSplices
.
add
(
headersToSplice
);
toSplices
.
addAll
(
pathVariables
);
requestParams
.
sort
(
Comparator
.
naturalOrder
());
toSplices
.
addAll
(
requestParams
);
toSplices
.
add
(
beanParams
);
return
toSplices
;
}
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
if
(
StringUtils
.
isBlank
(
appSecret
))
{
log
.
error
(
"app secret is blank"
);
}
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/signature/Signature.java
deleted
100644 → 0
View file @
2fddcc3c
package
io
.
geekidea
.
springbootplus
.
framework
.
signature
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.Target
;
import
static
java
.
lang
.
annotation
.
ElementType
.
METHOD
;
import
static
java
.
lang
.
annotation
.
ElementType
.
TYPE
;
import
static
java
.
lang
.
annotation
.
RetentionPolicy
.
RUNTIME
;
/**
* 签名注解
* 指定哪些接口或者哪些实体需要签名
* @Author linux
* @Date 2021年01月20日 08:32:00
* @Version 1.0
*/
@Target
({
TYPE
,
METHOD
})
@Retention
(
RUNTIME
)
@Documented
public
@interface
Signature
{
/**
* 按照order值排序
*/
String
ORDER_SORT
=
"ORDER_SORT"
;
/**
* 字典序排序
*/
String
ALPHA_SORT
=
"ALPHA_SORT"
;
boolean
resubmit
()
default
true
;
String
sort
()
default
Signature
.
ALPHA_SORT
;
}
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureException.java
deleted
100644 → 0
View file @
2fddcc3c
package
io
.
geekidea
.
springbootplus
.
framework
.
signature
;
/**
*
* @Author linux
* @Date 2021年01月20日 18:00
* @Version 1.0
*/
public
class
SignatureException
extends
RuntimeException
{
/**
*
* @Author linux
* @Date 2021年01月20日 06:01:17
* @Version 1.0
*/
public
SignatureException
(
String
code
)
{
super
(
code
);
}
public
SignatureException
(
String
code
,
String
message
)
{
super
(
code
+
":"
+
message
);
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureField.java
deleted
100644 → 0
View file @
2fddcc3c
package
io
.
geekidea
.
springbootplus
.
framework
.
signature
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.Target
;
import
static
java
.
lang
.
annotation
.
ElementType
.
FIELD
;
import
static
java
.
lang
.
annotation
.
RetentionPolicy
.
RUNTIME
;
/**
* 签名字段
* 指定哪些字段需要签名
* @Author linux
* @Date 2021年01月20日 08:43:28
* @Version 1.0
*/
@Target
({
FIELD
})
@Retention
(
RUNTIME
)
@Documented
public
@interface
SignatureField
{
//签名顺序
int
order
()
default
0
;
//字段name自定义值
String
customName
()
default
""
;
//字段value自定义值
String
customValue
()
default
""
;
}
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureHeaders.java
deleted
100644 → 0
View file @
2fddcc3c
package
io
.
geekidea
.
springbootplus
.
framework
.
signature
;
import
lombok.Data
;
import
lombok.ToString
;
import
java.util.Set
;
import
javax.validation.constraints.NotBlank
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
com.google.common.collect.Sets
;
/**
* 签名头信息类
* @Author linux
* @Date 2021年01月20日 16:28
* @Version 1.0
*/
@ConfigurationProperties
(
prefix
=
"can.signature"
)
@Signature
@Data
@ToString
public
class
SignatureHeaders
{
public
static
final
String
SIGNATURE_HEADERS_PREFIX
=
"can-signature-"
;
public
static
final
Set
<
String
>
SIGNATURE_HEADER_SET
=
Sets
.
newHashSet
();
private
static
final
String
HEADER_APP_ID
=
SIGNATURE_HEADERS_PREFIX
+
"appid"
;
private
static
final
String
HEADER_TIMESTAMP
=
SIGNATURE_HEADERS_PREFIX
+
"timestamp"
;
private
static
final
String
HEADER_NONCE
=
SIGNATURE_HEADERS_PREFIX
+
"nonce"
;
private
static
final
String
HEADER_SIGNATURE
=
SIGNATURE_HEADERS_PREFIX
+
"signature"
;
static
{
SIGNATURE_HEADER_SET
.
add
(
HEADER_APP_ID
);
SIGNATURE_HEADER_SET
.
add
(
HEADER_TIMESTAMP
);
SIGNATURE_HEADER_SET
.
add
(
HEADER_NONCE
);
SIGNATURE_HEADER_SET
.
add
(
HEADER_SIGNATURE
);
}
/**
* 线下分配的值
* 客户端和服务端各自保存appId对应的appSecret
*/
@NotBlank
(
message
=
"Header中缺少"
+
HEADER_APP_ID
)
@SignatureField
private
String
appid
;
/**
* 线下分配的值
* 客户端和服务端各自保存,与appId对应
*/
@SignatureField
private
String
appsecret
;
/**
* 时间戳,单位: ms
*/
@NotBlank
(
message
=
"Header中缺少"
+
HEADER_TIMESTAMP
)
@SignatureField
private
String
timestamp
;
/**
* 流水号【防止重复提交】; (备注:针对查询接口,流水号只用于日志落地,便于后期日志核查; 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求)
*/
@NotBlank
(
message
=
"Header中缺少"
+
HEADER_NONCE
)
@SignatureField
private
String
nonce
;
/**
* 签名
*/
@NotBlank
(
message
=
"Header中缺少"
+
HEADER_SIGNATURE
)
private
String
signature
;
}
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureProperties.java
deleted
100644 → 0
View file @
2fddcc3c
package
io
.
geekidea
.
springbootplus
.
framework
.
signature
;
import
lombok.Data
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.context.annotation.Configuration
;
/**
* Jwt参数配置
* @Author linux
* @Date 2020年12月28日 11:25:17
* @Version 1.0
*/
@Data
@Configuration
@ConfigurationProperties
(
prefix
=
"signature"
)
public
class
SignatureProperties
{
/**
* appSecret
*/
private
String
appId
;
/**
* appSecret
*/
private
String
appSecret
;
/**
* 同一个nonce 请求多长时间内不允许重复请求 单位:秒
*/
private
Long
expireTime
;
/**
* 同一个请求多长时间内有效 单位:秒
*/
private
Long
resubmitDuration
;
}
framework/src/main/java/io/geekidea/springbootplus/framework/signature/SignatureUtils.java
deleted
100644 → 0
View file @
2fddcc3c
package
io
.
geekidea
.
springbootplus
.
framework
.
signature
;
import
lombok.extern.slf4j.Slf4j
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.AnnotatedElement
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Base64
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.Set
;
import
java.util.TreeMap
;
import
java.util.UUID
;
import
org.apache.commons.codec.digest.HmacAlgorithms
;
import
org.apache.commons.codec.digest.HmacUtils
;
import
org.apache.commons.lang3.ClassUtils
;
import
org.apache.commons.lang3.RandomStringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.util.CollectionUtils
;
import
com.google.common.collect.Lists
;
/**
*
* @Author linux
* @Date 2021年01月20日 16:22
* @Version 1.0
*/
@Slf4j
public
class
SignatureUtils
{
private
static
final
byte
XOR_TOKEN
=
(
byte
)
0xFF
;
private
static
final
String
NOT_FOUND
=
"$_$"
;
private
static
final
String
DELIMETER
=
"^_^"
;
/**
* 客户端调用
* @param signatureHeaders header中需要的参数
* @param pathParams @PathVariable 需要的参数
* @param requestParamMap @RequestParam需要的参数
* @param entity @ModelAttribute 或者 @RequestBody需要的参数
*/
public
static
String
signature
(
SignatureHeaders
signatureHeaders
,
List
<
String
>
pathParams
,
Map
<
String
,
Object
>
requestParamMap
,
Object
entity
)
{
List
<
String
>
requestParams
=
Collections
.
emptyList
();
List
<
String
>
pathVariables
=
Collections
.
emptyList
();
String
beanParams
=
StringUtils
.
EMPTY
;
if
(!
CollectionUtils
.
isEmpty
(
pathParams
))
{
pathVariables
=
pathParams
;
}
if
(!
CollectionUtils
.
isEmpty
(
requestParamMap
))
{
requestParams
=
new
ArrayList
<>();
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
requestParamMap
.
entrySet
())
{
String
key
=
entry
.
getKey
();
Object
value
=
entry
.
getValue
();
List
<
String
>
values
=
Lists
.
newArrayList
();
if
(
value
.
getClass
().
isArray
())
{
//数组
for
(
int
j
=
0
;
j
<
Array
.
getLength
(
value
);
++
j
)
{
values
.
add
(
Array
.
get
(
value
,
j
).
toString
());
}
}
else
if
(
ClassUtils
.
isAssignable
(
Collection
.
class
,
value
.
getClass
()))
{
//集合
for
(
Object
o
:
(
Collection
<?>)
value
)
{
values
.
add
(
o
.
toString
());
}
}
else
{
//单个值
values
.
add
(
value
.
toString
());
}
values
.
sort
(
Comparator
.
naturalOrder
());
requestParams
.
add
(
key
+
"="
+
StringUtils
.
join
(
values
));
}
}
if
(!
Objects
.
isNull
(
entity
))
{
beanParams
=
toSplice
(
entity
);
}
String
headersToSplice
=
SignatureUtils
.
toSplice
(
signatureHeaders
);
List
<
String
>
toSplices
=
Lists
.
newArrayList
();
toSplices
.
add
(
headersToSplice
);
toSplices
.
addAll
(
pathVariables
);
requestParams
.
sort
(
Comparator
.
naturalOrder
());
toSplices
.
addAll
(
requestParams
);
toSplices
.
add
(
beanParams
);
return
SignatureUtils
.
signature
(
toSplices
.
toArray
(
new
String
[]{}),
signatureHeaders
.
getAppsecret
());
}
public
static
String
encode
(
String
text
,
String
appsecret
)
{
byte
token
=
(
byte
)
(
appsecret
.
hashCode
()
&
XOR_TOKEN
);
byte
[]
tb
=
text
.
getBytes
();
for
(
int
i
=
0
;
i
<
tb
.
length
;
++
i
)
{
tb
[
i
]
^=
token
;
}
return
Base64
.
getEncoder
().
encodeToString
(
tb
);
}
public
static
String
decode
(
String
text
,
String
appsecret
)
{
byte
token
=
(
byte
)
(
appsecret
.
hashCode
()
&
XOR_TOKEN
);
byte
[]
tb
=
Base64
.
getDecoder
().
decode
(
text
);
for
(
int
i
=
0
;
i
<
tb
.
length
;
++
i
)
{
tb
[
i
]
^=
token
;
}
return
new
String
(
tb
);
}
/** * 生成签名1 */
public
static
String
signature
(
String
[]
args
,
String
appsecret
)
{
String
splice
=
StringUtils
.
join
(
args
,
DELIMETER
);
System
.
out
.
println
(
"拼接结果: "
+
splice
);
return
new
HmacUtils
(
HmacAlgorithms
.
HMAC_SHA_256
,
appsecret
).
hmacHex
(
splice
);
}
/** * 生成签名2 */
public
static
String
signature
(
Object
object
,
String
appsecret
)
{
if
(
Objects
.
isNull
(
object
))
{
return
StringUtils
.
EMPTY
;
}
String
splice
=
toSplice
(
object
);
System
.
out
.
println
(
"拼接结果: "
+
splice
);
if
(
StringUtils
.
isBlank
(
splice
))
{
return
splice
;
}
return
new
HmacUtils
(
HmacAlgorithms
.
HMAC_SHA_256
,
appsecret
).
hmacHex
(
splice
);
}
/**
* 生成所有注有 SignatureField属性 key=value的 拼接 */
public
static
String
toSplice
(
Object
object
)
{
if
(
Objects
.
isNull
(
object
))
{
return
StringUtils
.
EMPTY
;
}
if
(
isAnnotated
(
object
.
getClass
(),
Signature
.
class
))
{
Signature
sg
=
findAnnotation
(
object
.
getClass
(),
Signature
.
class
);
if
(
Signature
.
ORDER_SORT
.
equals
(
sg
.
sort
()))
{
return
orderSignature
(
object
);
}
return
alphaSignature
(
object
);
}
return
toString
(
object
);
}
/**
* 生成唯一nonce随机数
* 仅供参考,不一定非得使用该方法
*/
public
static
String
generateNonce
()
{
return
new
HmacUtils
(
HmacAlgorithms
.
HMAC_SHA_256
,
UUID
.
randomUUID
().
toString
()).
hmacHex
(
RandomStringUtils
.
random
(
10
,
true
,
true
));
}
private
static
String
alphaSignature
(
Object
object
)
{
StringBuilder
result
=
new
StringBuilder
();
Map
<
String
,
String
>
map
=
new
TreeMap
<>();
for
(
Field
field
:
getAllFields
(
object
.
getClass
()))
{
if
(
field
.
isAnnotationPresent
(
SignatureField
.
class
))
{
field
.
setAccessible
(
true
);
try
{
if
(
isAnnotated
(
field
.
getType
(),
Signature
.
class
))
{
if
(!
Objects
.
isNull
(
field
.
get
(
object
)))
{
map
.
put
(
field
.
getName
(),
toSplice
(
field
.
get
(
object
)));
}
}
else
{
SignatureField
sgf
=
field
.
getAnnotation
(
SignatureField
.
class
);
if
(
StringUtils
.
isNotEmpty
(
sgf
.
customValue
())
||
!
Objects
.
isNull
(
field
.
get
(
object
)))
{
map
.
put
(
StringUtils
.
isNotBlank
(
sgf
.
customName
())
?
sgf
.
customName
()
:
field
.
getName
()
,
StringUtils
.
isNotEmpty
(
sgf
.
customValue
())
?
sgf
.
customValue
()
:
toString
(
field
.
get
(
object
)));
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"签名拼接(alphaSignature)异常"
,
e
);
}
}
}
for
(
Iterator
<
Map
.
Entry
<
String
,
String
>>
iterator
=
map
.
entrySet
().
iterator
();
iterator
.
hasNext
();
)
{
Map
.
Entry
<
String
,
String
>
entry
=
iterator
.
next
();
result
.
append
(
entry
.
getKey
()).
append
(
"="
).
append
(
entry
.
getValue
());
if
(
iterator
.
hasNext
())
{
result
.
append
(
DELIMETER
);
}
}
return
result
.
toString
();
}
private
static
String
orderSignature
(
Object
object
)
{
StringBuilder
result
=
new
StringBuilder
();
Set
<
OrderNode
>
set
=
new
HashSet
<>(
16
);
for
(
Field
field
:
getAllFields
(
object
.
getClass
()))
{
if
(
field
.
isAnnotationPresent
(
SignatureField
.
class
))
{
field
.
setAccessible
(
true
);
SignatureField
sgf
=
field
.
getAnnotation
(
SignatureField
.
class
);
try
{
if
(
isAnnotated
(
field
.
getType
(),
Signature
.
class
))
{
if
(!
Objects
.
isNull
(
field
.
get
(
object
)))
{
set
.
add
(
new
OrderNode
(
sgf
.
order
(),
field
.
getName
(),
toSplice
(
field
.
get
(
object
))));
}
}
else
{
if
(
StringUtils
.
isNotEmpty
(
sgf
.
customValue
())
||
!
Objects
.
isNull
(
field
.
get
(
object
)))
{
set
.
add
(
new
OrderNode
(
sgf
.
order
()
,
StringUtils
.
isNotBlank
(
sgf
.
customName
())
?
sgf
.
customName
()
:
field
.
getName
()
,
StringUtils
.
isNotEmpty
(
sgf
.
customValue
())
?
sgf
.
customValue
()
:
toString
(
field
.
get
(
object
))));
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"签名拼接(orderSignature)异常"
,
e
);
}
}
}
for
(
Iterator
<
OrderNode
>
iterator
=
set
.
iterator
();
iterator
.
hasNext
();
)
{
OrderNode
on
=
iterator
.
next
();
result
.
append
(
on
.
getName
()).
append
(
"="
).
append
(
on
.
getValue
());
if
(
iterator
.
hasNext
())
{
result
.
append
(
DELIMETER
);
}
}
return
result
.
toString
();
}
private
static
String
toString
(
Object
object
)
{
Class
<?>
type
=
object
.
getClass
();
if
(
BeanUtils
.
isSimpleProperty
(
type
))
{
return
object
.
toString
();
}
if
(
type
.
isArray
())
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
Array
.
getLength
(
object
);
++
i
)
{
sb
.
append
(
toSplice
(
Array
.
get
(
object
,
i
)));
}
return
sb
.
toString
();
}
if
(
ClassUtils
.
isAssignable
(
Collection
.
class
,
type
))
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
Iterator
<?>
iterator
=
((
Collection
<?>)
object
).
iterator
();
iterator
.
hasNext
();
)
{
sb
.
append
(
toSplice
(
iterator
.
next
()));
if
(
iterator
.
hasNext
())
{
sb
.
append
(
DELIMETER
);
}
}
return
sb
.
toString
();
}
if
(
ClassUtils
.
isAssignable
(
Map
.
class
,
type
))
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
Iterator
<?
extends
Map
.
Entry
<
String
,
?>>
iterator
=
((
Map
<
String
,
?>)
object
).
entrySet
().
iterator
();
iterator
.
hasNext
();
)
{
Map
.
Entry
<
String
,
?>
entry
=
iterator
.
next
();
if
(
Objects
.
isNull
(
entry
.
getValue
()))
{
continue
;
}
sb
.
append
(
entry
.
getKey
()).
append
(
"="
).
append
(
toSplice
(
entry
.
getValue
()));
if
(
iterator
.
hasNext
())
{
sb
.
append
(
DELIMETER
);
}
}
return
sb
.
toString
();
}
return
NOT_FOUND
;
}
private
static
<
A
extends
Annotation
>
A
findAnnotation
(
AnnotatedElement
element
,
Class
<
A
>
annotationType
)
{
return
element
.
getAnnotation
(
annotationType
);
}
private
static
boolean
isAnnotated
(
AnnotatedElement
element
,
Class
<?
extends
Annotation
>
annotationType
)
{
return
element
.
isAnnotationPresent
(
annotationType
);
}
public
static
Set
<
Field
>
getAllFields
(
final
Class
<?>
type
)
{
Set
<
Field
>
result
=
new
HashSet
<>(
16
);
for
(
Class
<?>
t
:
getAllSuperTypes
(
type
))
{
result
.
addAll
(
Arrays
.
asList
(
t
.
getDeclaredFields
()));
}
return
result
;
}
private
static
Set
<
Class
<?>>
getAllSuperTypes
(
final
Class
<?>
type
)
{
Set
<
Class
<?>>
result
=
new
LinkedHashSet
<>(
16
);
if
(
type
!=
null
&&
!
type
.
equals
(
Object
.
class
))
{
result
.
add
(
type
);
for
(
Class
<?>
supertype
:
getSuperTypes
(
type
))
{
result
.
addAll
(
getAllSuperTypes
(
supertype
));
}
}
return
result
;
}
private
static
Set
<
Class
<?>>
getSuperTypes
(
Class
<?>
type
)
{
Set
<
Class
<?>>
result
=
new
LinkedHashSet
<>();
Class
<?>
superclass
=
type
.
getSuperclass
();
Class
<?>[]
interfaces
=
type
.
getInterfaces
();
if
(
superclass
!=
null
&&
!
superclass
.
equals
(
Object
.
class
))
{
result
.
add
(
superclass
);
}
if
(
interfaces
.
length
>
0
)
{
result
.
addAll
(
Arrays
.
asList
(
interfaces
));
}
return
result
;
}
private
static
class
OrderNode
implements
Comparable
<
OrderNode
>
{
private
int
order
;
private
String
name
;
private
String
value
;
public
OrderNode
(
int
order
,
String
name
,
String
value
)
{
this
.
order
=
order
;
this
.
name
=
name
;
this
.
value
=
value
;
}
public
int
getOrder
()
{
return
order
;
}
public
void
setOrder
(
int
order
)
{
this
.
order
=
order
;
}
public
String
getValue
()
{
return
value
;
}
public
void
setValue
(
String
value
)
{
this
.
value
=
value
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
@Override
public
int
compareTo
(
OrderNode
o
)
{
if
(
this
.
order
==
o
.
order
)
{
return
this
.
name
.
compareTo
(
o
.
name
);
}
return
this
.
order
-
o
.
order
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
return
super
.
equals
(
obj
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
order
,
value
);
}
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/signature/ValidatorUtils.java
deleted
100644 → 0
View file @
2fddcc3c
package
io
.
geekidea
.
springbootplus
.
framework
.
signature
;
import
java.util.Iterator
;
import
java.util.Optional
;
import
java.util.Set
;
import
javax.validation.ConstraintViolation
;
import
javax.validation.Validation
;
import
javax.validation.Validator
;
import
org.hibernate.validator.HibernateValidator
;
/**
*
* @Author linux
* @Date 2021年01月20日 18:18
* @Version 1.0
*/
public
class
ValidatorUtils
{
private
final
static
Validator
VALIDATOR_FAST
=
Validation
.
byProvider
(
HibernateValidator
.
class
).
configure
().
failFast
(
true
).
buildValidatorFactory
().
getValidator
();
private
final
static
Validator
VALIDATOR_ALL
=
Validation
.
byProvider
(
HibernateValidator
.
class
).
configure
().
failFast
(
false
).
buildValidatorFactory
().
getValidator
();
/**
* 校验遇到第一个不合法的字段直接返回不合法字段,后续字段不再校验
* @Time 2020年6月22日 上午11:36:13
* @param <T>
* @param domain
* @return
*/
public
static
<
T
>
Optional
<
String
>
validateFast
(
T
domain
)
{
Set
<
ConstraintViolation
<
T
>>
validateResult
=
VALIDATOR_FAST
.
validate
(
domain
);
if
(
validateResult
.
size
()
>
0
)
{
System
.
out
.
println
(
validateResult
.
iterator
().
next
().
getPropertyPath
()
+
":"
+
validateResult
.
iterator
().
next
().
getMessage
());
}
StringBuilder
sb
=
new
StringBuilder
();
for
(
Iterator
<
ConstraintViolation
<
T
>>
iterator
=
validateResult
.
iterator
();
iterator
.
hasNext
();
)
{
sb
.
append
(
iterator
.
next
().
getMessage
());
if
(
iterator
.
hasNext
())
{
sb
.
append
(
" ,"
);
}
}
return
Optional
.
of
(
sb
.
toString
());
}
/**
* 校验所有字段并返回不合法字段
* @Time 2020年6月22日 上午11:36:55
* @param <T>
* @param domain
* @return
*/
public
static
<
T
>
Optional
<
String
>
validateAll
(
T
domain
)
{
Set
<
ConstraintViolation
<
T
>>
validateResult
=
VALIDATOR_ALL
.
validate
(
domain
);
if
(
validateResult
.
size
()
>
0
)
{
for
(
ConstraintViolation
<
T
>
cv
:
validateResult
)
{
System
.
out
.
println
(
cv
.
getPropertyPath
()
+
":"
+
cv
.
getMessage
());
}
}
StringBuilder
sb
=
new
StringBuilder
();
for
(
Iterator
<
ConstraintViolation
<
T
>>
iterator
=
validateResult
.
iterator
();
iterator
.
hasNext
();
)
{
sb
.
append
(
iterator
.
next
().
getMessage
());
if
(
iterator
.
hasNext
())
{
sb
.
append
(
" ,"
);
}
}
return
Optional
.
of
(
sb
.
toString
());
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment