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
6a1ec9f7
Commit
6a1ec9f7
authored
Apr 15, 2022
by
罗长华
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成api签名认证服务端处理逻辑
parent
e37a2d41
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
771 additions
and
106 deletions
+771
-106
bootstrap/src/main/java/io/geekidea/springbootplus/config/ShiroConfig.java
+34
-11
bootstrap/src/main/java/io/geekidea/springbootplus/config/SpringBootPlusWebMvcConfig.java
+20
-6
core/src/main/java/com/wecloud/im/entity/ImApplication.java
+12
-4
core/src/main/java/com/wecloud/im/param/RegisterClientParam.java
+0
-7
core/src/main/java/com/wecloud/im/service/impl/ImApplicationServiceImpl.java
+18
-10
core/src/main/java/com/wecloud/im/service/impl/ImClientServiceImpl.java
+5
-4
framework/src/main/java/io/geekidea/springbootplus/framework/core/filter/ChannelFilter.java
+46
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/Application.java
+34
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/ApplicationService.java
+21
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/BinaryUtil.java
+42
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/HmacSHA256Signature.java
+83
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/RequestWrapper.java
+48
-34
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignUtils.java
+139
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignatureAuthFilter.java
+78
-6
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignatureAuthRealm.java
+48
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignatureAuthToken.java
+49
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignatureChecker.java
+40
-17
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/util/JwtUtil.java
+9
-7
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/util/SecurityUtils.java
+45
-0
No files found.
bootstrap/src/main/java/io/geekidea/springbootplus/config/ShiroConfig.java
View file @
6a1ec9f7
...
...
@@ -16,7 +16,6 @@
package
io
.
geekidea
.
springbootplus
.
config
;
import
com.alibaba.fastjson.JSON
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.ShiroPermissionProperties
;
import
io.geekidea.springbootplus.config.properties.ShiroProperties
;
...
...
@@ -26,8 +25,21 @@ import io.geekidea.springbootplus.framework.shiro.jwt.JwtCredentialsMatcher;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtFilter
;
import
io.geekidea.springbootplus.framework.shiro.jwt.realm.JwtRealmAppUser
;
import
io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService
;
import
io.geekidea.springbootplus.framework.shiro.signature.ApplicationService
;
import
io.geekidea.springbootplus.framework.shiro.signature.SignatureAuthFilter
;
import
io.geekidea.springbootplus.framework.shiro.signature.SignatureAuthRealm
;
import
io.geekidea.springbootplus.framework.util.IniUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
javax.servlet.DispatcherType
;
import
javax.servlet.Filter
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.MapUtils
;
import
org.apache.commons.lang3.ArrayUtils
;
...
...
@@ -54,13 +66,7 @@ import org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.filter.DelegatingFilterProxy
;
import
javax.servlet.DispatcherType
;
import
javax.servlet.Filter
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
com.alibaba.fastjson.JSON
;
/**
* Shiro配置
...
...
@@ -114,6 +120,18 @@ public class ShiroConfig {
return
jwtRealm
;
}
/**
* 用户客户端Realm
* @Author luozh
* @Date 2022年04月15日 05:27:00
* @param
* @Return
*/
public
SignatureAuthRealm
signatureAuthRealm
()
{
SignatureAuthRealm
realm
=
new
SignatureAuthRealm
();
return
realm
;
}
/**
* subject不存储到Session中
...
...
@@ -148,6 +166,7 @@ public class ShiroConfig {
List
<
Realm
>
realms
=
new
ArrayList
<>();
// realms.add(jwtRealmSystem(sysLoginRedisService));
realms
.
add
(
jwtRealmAppUser
(
appLoginRedisService
));
realms
.
add
(
signatureAuthRealm
());
// realms.add(jwtRealmMerchant(merchantLoginRedisService));
// 用户数据连接器
...
...
@@ -171,13 +190,15 @@ public class ShiroConfig {
public
ShiroFilterFactoryBean
shiroFilterFactoryBean
(
SecurityManager
securityManager
,
ShiroLoginService
shiroLoginService
,
ShiroProperties
shiroProperties
,
JwtProperties
jwtProperties
)
{
JwtProperties
jwtProperties
,
ApplicationService
applicationService
)
{
ShiroFilterFactoryBean
shiroFilterFactoryBean
=
new
ShiroFilterFactoryBean
();
// 设置安全管理器
shiroFilterFactoryBean
.
setSecurityManager
(
securityManager
);
// 设置过滤器
Map
<
String
,
Filter
>
filterMap
=
getFilterMap
(
shiroLoginService
);
Map
<
String
,
Filter
>
filterMap
=
getFilterMap
(
shiroLoginService
,
applicationService
);
shiroFilterFactoryBean
.
setFilters
(
filterMap
);
// 设置过滤器顺序
Map
<
String
,
String
>
filterChainMap
=
getFilterChainDefinitionMap
(
shiroProperties
);
...
...
@@ -191,9 +212,10 @@ public class ShiroConfig {
*
* @return
*/
private
Map
<
String
,
Filter
>
getFilterMap
(
ShiroLoginService
shiroLoginService
)
{
private
Map
<
String
,
Filter
>
getFilterMap
(
ShiroLoginService
shiroLoginService
,
ApplicationService
applicationService
)
{
Map
<
String
,
Filter
>
filterMap
=
new
LinkedHashMap
<>();
filterMap
.
put
(
JWT_FILTER_NAME
,
new
JwtFilter
(
shiroLoginService
));
filterMap
.
put
(
"signatureAuthFilter"
,
new
SignatureAuthFilter
(
applicationService
));
return
filterMap
;
}
...
...
@@ -256,6 +278,7 @@ public class ShiroConfig {
// 如果启用shiro,则设置最后一个设置为JWTFilter,否则全部路径放行
if
(
shiroProperties
.
isEnable
())
{
filterChainDefinitionMap
.
put
(
"/imClient/registerClient"
,
"signatureAuthFilter"
);
filterChainDefinitionMap
.
put
(
"/**"
,
JWT_FILTER_NAME
);
}
else
{
filterChainDefinitionMap
.
put
(
"/**"
,
ANON
);
...
...
bootstrap/src/main/java/io/geekidea/springbootplus/config/SpringBootPlusWebMvcConfig.java
View file @
6a1ec9f7
...
...
@@ -16,18 +16,20 @@
package
io
.
geekidea
.
springbootplus
.
config
;
import
com.alibaba.fastjson.JSON
;
import
com.wecloud.im.interceptor.DownloadInterceptor
;
import
com.wecloud.im.interceptor.ResourceInterceptor
;
import
com.wecloud.im.interceptor.UploadInterceptor
;
import
io.geekidea.springbootplus.config.properties.SpringBootPlusFilterProperties
;
import
io.geekidea.springbootplus.config.properties.SpringBootPlusInterceptorProperties
;
import
io.geekidea.springbootplus.config.properties.SpringBootPlusProperties
;
import
io.geekidea.springbootplus.framework.core.filter.ChannelFilter
;
import
io.geekidea.springbootplus.framework.core.filter.RequestDetailFilter
;
import
io.geekidea.springbootplus.framework.core.interceptor.PermissionInterceptor
;
import
io.geekidea.springbootplus.framework.core.xss.XssFilter
;
import
io.geekidea.springbootplus.framework.util.IniUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
java.util.Map
;
import
javax.annotation.PostConstruct
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.web.servlet.FilterRegistrationBean
;
...
...
@@ -37,8 +39,10 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import
javax.annotation.PostConstruct
;
import
java.util.Map
;
import
com.alibaba.fastjson.JSON
;
import
com.wecloud.im.interceptor.DownloadInterceptor
;
import
com.wecloud.im.interceptor.ResourceInterceptor
;
import
com.wecloud.im.interceptor.UploadInterceptor
;
/**
* WebMvc配置
...
...
@@ -100,6 +104,16 @@ public class SpringBootPlusWebMvcConfig implements WebMvcConfigurer {
return
filterRegistrationBean
;
}
@Bean
public
FilterRegistrationBean
repeatedlyReadFilter
()
{
FilterRegistrationBean
registration
=
new
FilterRegistrationBean
();
ChannelFilter
repeatedlyReadFilter
=
new
ChannelFilter
();
registration
.
setFilter
(
repeatedlyReadFilter
);
registration
.
setOrder
(
3
);
registration
.
addUrlPatterns
(
"/*"
);
return
registration
;
}
/**
* 自定义权限拦截器
...
...
core/src/main/java/com/wecloud/im/entity/ImApplication.java
View file @
6a1ec9f7
package
com
.
wecloud
.
im
.
entity
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
io.geekidea.springbootplus.framework.common.entity.BaseEntity
;
import
io.geekidea.springbootplus.framework.shiro.signature.Application
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.experimental.Accessors
;
import
javax.validation.constraints.NotNull
;
import
java.util.Date
;
import
javax.validation.constraints.NotNull
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
/**
* 第三方应用表
*
...
...
@@ -22,7 +25,7 @@ import java.util.Date;
@Accessors
(
chain
=
true
)
@EqualsAndHashCode
(
callSuper
=
true
)
@ApiModel
(
value
=
"ImApplication对象"
)
public
class
ImApplication
extends
BaseEntity
{
public
class
ImApplication
extends
BaseEntity
implements
Application
{
private
static
final
long
serialVersionUID
=
1L
;
@NotNull
(
message
=
"应用appid不能为空"
)
...
...
@@ -65,4 +68,9 @@ public class ImApplication extends BaseEntity {
@ApiModelProperty
(
"创建会话时对比扩展字段 0不 1是"
)
private
Integer
contrastExtendedFieldStatus
;
@Override
public
Boolean
isActive
()
{
return
true
;
}
}
core/src/main/java/com/wecloud/im/param/RegisterClientParam.java
View file @
6a1ec9f7
...
...
@@ -15,13 +15,6 @@ import javax.validation.constraints.NotNull;
public
class
RegisterClientParam
{
/**
* appKey
*/
@NotNull
(
message
=
"appKey 不能为空"
)
@ApiModelProperty
(
"appKey"
)
private
String
appKey
;
/**
* app 用户id
*/
@NotNull
(
message
=
"用户id 不能为空"
)
...
...
core/src/main/java/com/wecloud/im/service/impl/ImApplicationServiceImpl.java
View file @
6a1ec9f7
package
com
.
wecloud
.
im
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.OrderItem
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.wecloud.im.entity.ImApplication
;
import
com.wecloud.im.mapper.ImApplicationMapper
;
import
com.wecloud.im.param.ImApplicationPageParam
;
import
com.wecloud.im.param.ImApplicationQueryVo
;
import
com.wecloud.im.service.ImApplicationService
;
import
io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl
;
import
io.geekidea.springbootplus.framework.core.pagination.PageInfo
;
import
io.geekidea.springbootplus.framework.core.pagination.Paging
;
import
io.geekidea.springbootplus.framework.shiro.signature.Application
;
import
io.geekidea.springbootplus.framework.shiro.signature.ApplicationService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cache.annotation.CacheConfig
;
import
org.springframework.cache.annotation.CacheEvict
;
...
...
@@ -20,6 +14,16 @@ import org.springframework.cache.annotation.Cacheable;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.OrderItem
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.wecloud.im.entity.ImApplication
;
import
com.wecloud.im.mapper.ImApplicationMapper
;
import
com.wecloud.im.param.ImApplicationPageParam
;
import
com.wecloud.im.param.ImApplicationQueryVo
;
import
com.wecloud.im.service.ImApplicationService
;
/**
* 第三方应用表 服务实现类
*
...
...
@@ -29,7 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Service
@CacheConfig
(
cacheNames
=
"appl"
)
public
class
ImApplicationServiceImpl
extends
BaseServiceImpl
<
ImApplicationMapper
,
ImApplication
>
implements
ImApplicationService
{
public
class
ImApplicationServiceImpl
extends
BaseServiceImpl
<
ImApplicationMapper
,
ImApplication
>
implements
ImApplicationService
,
ApplicationService
{
@Autowired
private
ImApplicationMapper
imApplicationMapper
;
...
...
@@ -90,4 +94,8 @@ public class ImApplicationServiceImpl extends BaseServiceImpl<ImApplicationMappe
return
new
Paging
<
ImApplicationQueryVo
>(
iPage
);
}
@Override
public
Application
getApplication
(
String
appKey
)
{
return
getCacheAppByAppKey
(
appKey
);
}
}
core/src/main/java/com/wecloud/im/service/impl/ImClientServiceImpl.java
View file @
6a1ec9f7
...
...
@@ -6,6 +6,7 @@ import io.geekidea.springbootplus.framework.core.pagination.PageInfo;
import
io.geekidea.springbootplus.framework.core.pagination.Paging
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.SecurityUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
java.util.Date
;
...
...
@@ -326,16 +327,16 @@ public class ImClientServiceImpl extends BaseServiceImpl<ImClientMapper, ImClien
@Override
public
Long
registerClient
(
RegisterClientParam
param
)
{
ImApplication
imApplication
=
imApplicationService
.
getCacheAppByAppKey
(
param
.
getAppKey
()
);
Long
appId
=
SecurityUtils
.
getCurrentAppId
(
);
// 判断client是否存在
ImClient
imClient
=
getOne
(
new
QueryWrapper
<
ImClient
>().
lambda
()
.
eq
(
ImClient:
:
getFkAppid
,
imApplication
.
getId
()
)
.
eq
(
ImClient:
:
getFkAppid
,
appId
)
.
eq
(
ImClient:
:
getClientId
,
param
.
getUserId
()));
if
(
imClient
==
null
)
{
imClient
=
new
ImClient
();
imClient
.
setId
(
SnowflakeUtil
.
getId
());
imClient
.
setFkAppid
(
imApplication
.
getId
()
);
imClient
.
setFkAppid
(
appId
);
imClient
.
setClientId
(
param
.
getUserId
().
toString
());
imClient
.
setHeadPortrait
(
param
.
getHeadPortrait
());
imClient
.
setNickname
(
param
.
getNickname
());
...
...
@@ -343,7 +344,7 @@ public class ImClientServiceImpl extends BaseServiceImpl<ImClientMapper, ImClien
ImClientDevice
imClientDevice
=
new
ImClientDevice
();
imClientDevice
.
setId
(
SnowflakeUtil
.
getId
());
imClientDevice
.
setFkAppid
(
imApplication
.
getId
()
);
imClientDevice
.
setFkAppid
(
appId
);
imClientDevice
.
setFkClientId
(
imClient
.
getId
());
imClientDevice
.
setValid
(
1
);
imClientDevice
.
setDeviceType
(
param
.
getDeviceType
());
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/core/filter/ChannelFilter.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
core
.
filter
;
import
io.geekidea.springbootplus.framework.shiro.signature.RequestWrapper
;
import
java.io.IOException
;
import
javax.servlet.Filter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.FilterConfig
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.annotation.WebFilter
;
import
javax.servlet.http.HttpServletRequest
;
/**
*
* @Author luozh
* @Date 2022年04月15日 10:12
* @Version 1.0
*/
@WebFilter
(
urlPatterns
=
"/*"
,
filterName
=
"channelFilter"
)
public
class
ChannelFilter
implements
Filter
{
@Override
public
void
init
(
FilterConfig
filterConfig
)
throws
ServletException
{
}
@Override
public
void
doFilter
(
ServletRequest
servletRequest
,
ServletResponse
servletResponse
,
FilterChain
filterChain
)
throws
IOException
,
ServletException
{
ServletRequest
requestWrapper
=
null
;
if
(
servletRequest
instanceof
HttpServletRequest
)
{
requestWrapper
=
new
RequestWrapper
((
HttpServletRequest
)
servletRequest
);
}
if
(
requestWrapper
==
null
)
{
filterChain
.
doFilter
(
servletRequest
,
servletResponse
);
}
else
{
filterChain
.
doFilter
(
requestWrapper
,
servletResponse
);
}
}
@Override
public
void
destroy
()
{
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/Application.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
/**
*
* @Author luozh
* @Date 2022年04月15日 19:21
* @Version 1.0
*/
public
interface
Application
{
/**
* 获取id
* @return
*/
Long
getId
();
/**
* 获取appKey
* @return
*/
String
getAppKey
();
/**
* 获取AppSecret
* @return
*/
String
getAppSecret
();
/**
* 客户端是否有效
* @return
*/
Boolean
isActive
();
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/ApplicationService.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
/**
*
* @Author luozh
* @Date 2022年04月15日 11:02
* @Version 1.0
*/
public
interface
ApplicationService
{
/**
* 根据appKey获取对应的AppSecret
* @Author luozh
* @Date 2022年04月15日 11:02:53
* @param appKey
* @Return
*/
Application
getApplication
(
String
appKey
);
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/BinaryUtil.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
org.apache.commons.codec.binary.Base64
;
public
class
BinaryUtil
{
private
static
final
char
[]
HEX_DIGITS
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
};
public
static
String
toBase64String
(
byte
[]
binaryData
)
{
return
new
String
(
Base64
.
encodeBase64
(
binaryData
));
}
public
static
byte
[]
fromBase64String
(
String
base64String
)
{
return
Base64
.
decodeBase64
(
base64String
);
}
public
static
byte
[]
calculateMd5
(
byte
[]
binaryData
)
{
MessageDigest
messageDigest
=
null
;
try
{
messageDigest
=
MessageDigest
.
getInstance
(
"MD5"
);
}
catch
(
NoSuchAlgorithmException
e
)
{
throw
new
RuntimeException
(
"MD5 algorithm not found."
);
}
messageDigest
.
update
(
binaryData
);
return
messageDigest
.
digest
();
}
public
static
String
encodeMD5
(
byte
[]
binaryData
)
{
byte
[]
md5Bytes
=
calculateMd5
(
binaryData
);
int
len
=
md5Bytes
.
length
;
char
buf
[]
=
new
char
[
len
*
2
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
buf
[
i
*
2
]
=
HEX_DIGITS
[(
md5Bytes
[
i
]
>>>
4
)
&
0x0f
];
buf
[
i
*
2
+
1
]
=
HEX_DIGITS
[
md5Bytes
[
i
]
&
0x0f
];
}
return
new
String
(
buf
);
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/HmacSHA256Signature.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
/**
*
* @Author luozh
* @Date 2022年04月14日 14:55
* @Version 1.0
*/
import
java.io.UnsupportedEncodingException
;
import
java.security.InvalidKeyException
;
import
java.security.NoSuchAlgorithmException
;
import
javax.crypto.Mac
;
import
javax.crypto.spec.SecretKeySpec
;
/**
* Used for computing Hmac-SHA256 signature.
*/
public
class
HmacSHA256Signature
{
/* The default encoding. */
private
static
final
String
DEFAULT_ENCODING
=
"UTF-8"
;
/* Signature method. */
private
static
final
String
ALGORITHM
=
"HmacSHA256"
;
/* Signature version. */
private
static
final
String
VERSION
=
"1"
;
private
static
final
Object
LOCK
=
new
Object
();
/* Prototype of the Mac instance. */
private
static
Mac
macInstance
;
public
String
getAlgorithm
()
{
return
ALGORITHM
;
}
public
String
getVersion
()
{
return
VERSION
;
}
public
String
computeSignature
(
String
key
,
String
data
)
{
try
{
byte
[]
signData
=
sign
(
key
.
getBytes
(
DEFAULT_ENCODING
),
data
.
getBytes
(
DEFAULT_ENCODING
),
macInstance
,
LOCK
,
ALGORITHM
);
return
BinaryUtil
.
toBase64String
(
signData
);
}
catch
(
UnsupportedEncodingException
ex
)
{
throw
new
RuntimeException
(
"Unsupported algorithm: "
+
DEFAULT_ENCODING
,
ex
);
}
}
protected
byte
[]
sign
(
byte
[]
key
,
byte
[]
data
,
Mac
macInstance
,
Object
lock
,
String
algorithm
)
{
try
{
// Because Mac.getInstance(String) calls a synchronized method, it
// could block on
// invoked concurrently, so use prototype pattern to improve perf.
if
(
macInstance
==
null
)
{
synchronized
(
lock
)
{
if
(
macInstance
==
null
)
{
macInstance
=
Mac
.
getInstance
(
algorithm
);
}
}
}
Mac
mac
;
try
{
mac
=
(
Mac
)
macInstance
.
clone
();
}
catch
(
CloneNotSupportedException
e
)
{
// If it is not clonable, create a new one.
mac
=
Mac
.
getInstance
(
algorithm
);
}
mac
.
init
(
new
SecretKeySpec
(
key
,
algorithm
));
return
mac
.
doFinal
(
data
);
}
catch
(
NoSuchAlgorithmException
ex
)
{
throw
new
RuntimeException
(
"Unsupported algorithm: "
+
algorithm
,
ex
);
}
catch
(
InvalidKeyException
ex
)
{
throw
new
RuntimeException
(
"Invalid key: "
+
key
,
ex
);
}
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/RequestWrapper.java
View file @
6a1ec9f7
...
...
@@ -2,8 +2,8 @@ package io.geekidea.springbootplus.framework.shiro.signature;
import
java.io.BufferedReader
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
javax.servlet.ReadListener
;
...
...
@@ -11,8 +11,6 @@ import javax.servlet.ServletInputStream;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequestWrapper
;
import
org.apache.commons.io.IOUtils
;
/**
* 对HttpServletRequest进行重写,
* 1、用来接收application/json参数数据类型,即@RequestBody注解标注的参数,解决多次读取问题
...
...
@@ -26,36 +24,50 @@ import org.apache.commons.io.IOUtils;
* @Version 1.0
*/
public
class
RequestWrapper
extends
HttpServletRequestWrapper
{
private
final
String
body
;
//参数字节数组
private
byte
[]
requestBody
;
//Http请求对象
private
HttpServletRequest
request
;
public
RequestWrapper
(
HttpServletRequest
request
)
throws
IOException
{
public
RequestWrapper
(
HttpServletRequest
request
)
{
super
(
request
);
this
.
request
=
request
;
StringBuilder
stringBuilder
=
new
StringBuilder
();
BufferedReader
bufferedReader
=
null
;
InputStream
inputStream
=
null
;
try
{
inputStream
=
request
.
getInputStream
();
if
(
inputStream
!=
null
)
{
bufferedReader
=
new
BufferedReader
(
new
InputStreamReader
(
inputStream
));
char
[]
charBuffer
=
new
char
[
128
];
int
bytesRead
=
-
1
;
while
((
bytesRead
=
bufferedReader
.
read
(
charBuffer
))
>
0
)
{
stringBuilder
.
append
(
charBuffer
,
0
,
bytesRead
);
}
}
else
{
stringBuilder
.
append
(
""
);
}
}
catch
(
IOException
ex
)
{
}
finally
{
if
(
inputStream
!=
null
)
{
try
{
inputStream
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
if
(
bufferedReader
!=
null
)
{
try
{
bufferedReader
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
body
=
stringBuilder
.
toString
();
}
/**
* @return
* @throws IOException
*/
@Override
public
ServletInputStream
getInputStream
()
throws
IOException
{
/**
* 每次调用此方法时将数据流中的数据读取出来,然后再回填到InputStream之中
* 解决通过@RequestBody和@RequestParam(POST方式)读取一次后控制器拿不到参数问题
*/
if
(
null
==
this
.
requestBody
)
{
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
IOUtils
.
copy
(
request
.
getInputStream
(),
baos
);
this
.
requestBody
=
baos
.
toByteArray
();
}
final
ByteArrayInputStream
bais
=
new
ByteArrayInputStream
(
requestBody
);
return
new
ServletInputStream
()
{
final
ByteArrayInputStream
byteArrayInputStream
=
new
ByteArrayInputStream
(
body
.
getBytes
());
ServletInputStream
servletInputStream
=
new
ServletInputStream
()
{
@Override
public
boolean
isFinished
()
{
return
false
;
...
...
@@ -67,23 +79,25 @@ public class RequestWrapper extends HttpServletRequestWrapper {
}
@Override
public
void
setReadListener
(
ReadListener
listener
)
{
public
void
setReadListener
(
ReadListener
readListener
)
{
}
@Override
public
int
read
()
{
return
b
ais
.
read
();
public
int
read
()
throws
IOException
{
return
b
yteArrayInputStream
.
read
();
}
};
}
return
servletInputStream
;
public
byte
[]
getRequestBody
()
{
return
requestBody
;
}
@Override
public
BufferedReader
getReader
()
throws
IOException
{
return
new
BufferedReader
(
new
InputStreamReader
(
this
.
getInputStream
()));
}
public
String
getBody
()
{
return
this
.
body
;
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignUtils.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
import
java.io.UnsupportedEncodingException
;
import
java.util.Map
;
import
java.util.TreeMap
;
import
cn.hutool.core.lang.Assert
;
/**
* 签名工具类
* @Author luozh
* @Date 2022年04月14日 11:32o
* @Version 1.0
*/
public
class
SignUtils
{
public
static
final
String
IM_PREFIX
=
"x-im-"
;
public
static
final
String
CONTENT_TYPE
=
"Content-Type"
;
public
static
final
String
DATE
=
"Date"
;
public
static
final
String
NEW_LINE
=
"\n"
;
public
static
String
buildCanonicalString
(
String
method
,
String
resourcePath
,
Map
<
String
,
String
>
headers
,
Map
<
String
,
String
>
parameters
)
{
StringBuilder
canonicalString
=
new
StringBuilder
();
canonicalString
.
append
(
method
).
append
(
NEW_LINE
);
TreeMap
<
String
,
String
>
fixedHeadersToSign
=
new
TreeMap
<>();
TreeMap
<
String
,
String
>
canonicalizedImHeadersToSign
=
new
TreeMap
<>();
if
(
headers
!=
null
)
{
for
(
Map
.
Entry
<
String
,
String
>
header
:
headers
.
entrySet
())
{
if
(
header
.
getKey
()
!=
null
)
{
String
lowerKey
=
header
.
getKey
().
toLowerCase
();
if
(
lowerKey
.
equals
(
CONTENT_TYPE
.
toLowerCase
())
||
lowerKey
.
equals
(
DATE
.
toLowerCase
()))
{
fixedHeadersToSign
.
put
(
lowerKey
,
header
.
getValue
().
trim
());
}
else
if
(
lowerKey
.
startsWith
(
IM_PREFIX
))
{
canonicalizedImHeadersToSign
.
put
(
lowerKey
,
header
.
getValue
().
trim
());
}
}
}
}
if
(!
fixedHeadersToSign
.
containsKey
(
CONTENT_TYPE
.
toLowerCase
()))
{
fixedHeadersToSign
.
put
(
CONTENT_TYPE
.
toLowerCase
(),
""
);
}
// Append fixed headers to sign to canonical string
for
(
Map
.
Entry
<
String
,
String
>
entry
:
fixedHeadersToSign
.
entrySet
())
{
Object
value
=
entry
.
getValue
();
canonicalString
.
append
(
value
);
canonicalString
.
append
(
NEW_LINE
);
}
// Append canonicalized im headers to sign to canonical string
for
(
Map
.
Entry
<
String
,
String
>
entry
:
canonicalizedImHeadersToSign
.
entrySet
())
{
String
key
=
entry
.
getKey
();
Object
value
=
entry
.
getValue
();
canonicalString
.
append
(
key
).
append
(
':'
).
append
(
value
).
append
(
NEW_LINE
);
}
// Append canonical resource to canonical string
canonicalString
.
append
(
buildCanonicalizedResource
(
resourcePath
,
parameters
));
return
canonicalString
.
toString
();
}
private
static
String
buildCanonicalizedResource
(
String
resourcePath
,
Map
<
String
,
String
>
parameters
)
{
Assert
.
isTrue
(
resourcePath
.
startsWith
(
"/"
),
"Resource path should start with slash character"
);
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
uriEncoding
(
resourcePath
));
if
(
parameters
!=
null
)
{
TreeMap
<
String
,
String
>
canonicalizedParams
=
new
TreeMap
<
String
,
String
>();
for
(
Map
.
Entry
<
String
,
String
>
param
:
parameters
.
entrySet
())
{
if
(
param
.
getValue
()
!=
null
)
{
canonicalizedParams
.
put
(
uriEncoding
(
param
.
getKey
()),
uriEncoding
(
param
.
getValue
()));
}
else
{
canonicalizedParams
.
put
(
uriEncoding
(
param
.
getKey
()),
null
);
}
}
char
separator
=
'?'
;
for
(
Map
.
Entry
<
String
,
String
>
entry
:
canonicalizedParams
.
entrySet
())
{
builder
.
append
(
separator
);
builder
.
append
(
entry
.
getKey
());
if
(
entry
.
getValue
()
!=
null
&&
!
entry
.
getValue
().
isEmpty
())
{
builder
.
append
(
"="
).
append
(
entry
.
getValue
());
}
separator
=
'&'
;
}
}
return
builder
.
toString
();
}
public
static
String
uriEncoding
(
String
uri
)
{
String
result
=
""
;
try
{
for
(
char
c
:
uri
.
toCharArray
())
{
if
((
c
>=
'A'
&&
c
<=
'Z'
)
||
(
c
>=
'a'
&&
c
<=
'z'
)
||
(
c
>=
'0'
&&
c
<=
'9'
)
||
c
==
'_'
||
c
==
'-'
||
c
==
'~'
||
c
==
'.'
)
{
result
+=
c
;
}
else
if
(
c
==
'/'
)
{
result
+=
"%2F"
;
}
else
{
byte
[]
b
;
b
=
Character
.
toString
(
c
).
getBytes
(
"utf-8"
);
for
(
int
i
=
0
;
i
<
b
.
length
;
i
++)
{
int
k
=
b
[
i
];
if
(
k
<
0
)
{
k
+=
256
;
}
result
+=
"%"
+
Integer
.
toHexString
(
k
).
toUpperCase
();
}
}
}
}
catch
(
UnsupportedEncodingException
e
)
{
throw
new
IllegalStateException
(
e
);
}
return
result
;
}
public
static
String
buildSignature
(
String
secretAccessKey
,
String
httpMethod
,
String
resourcePath
,
Map
<
String
,
String
>
headers
,
Map
<
String
,
String
>
parameters
)
{
String
canonicalString
=
buildCanonicalString
(
httpMethod
,
resourcePath
,
headers
,
parameters
);
return
new
HmacSHA256Signature
().
computeSignature
(
secretAccessKey
,
canonicalString
);
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignatureAuthFilter.java
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
import
lombok.extern.slf4j.Slf4j
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.validation.constraints.NotNull
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.authc.AuthenticationToken
;
import
org.apache.shiro.web.filter.authc.AuthenticatingFilter
;
import
org.
springframework.web.context.request.RequestContextHolder
;
import
org.
springframework.web.context.request.ServletRequestAttribute
s
;
import
org.
apache.shiro.web.servlet.ShiroHttpServletRequest
;
import
org.
apache.shiro.web.util.WebUtil
s
;
/**
* shiro 用户签名认证
...
...
@@ -17,27 +20,96 @@ import org.springframework.web.context.request.ServletRequestAttributes;
* @Date 2022年04月14日 16:43
* @Version 1.0
*/
@Slf4j
public
class
SignatureAuthFilter
extends
AuthenticatingFilter
{
private
static
final
String
AUTHORIZATION
=
"Authorization"
;
private
ApplicationService
applicationService
;
public
SignatureAuthFilter
(
@NotNull
ApplicationService
applicationService
)
{
if
(
applicationService
==
null
)
{
throw
new
IllegalArgumentException
(
"application service must not be null"
);
}
this
.
applicationService
=
applicationService
;
}
@Override
protected
AuthenticationToken
createToken
(
ServletRequest
servletRequest
,
ServletResponse
servletResponse
)
throws
Exception
{
ShiroHttpServletRequest
ShiroHttpServletRequest
=
(
ShiroHttpServletRequest
)
servletRequest
;
HttpServletRequest
request
=
(
(
ServletRequestAttributes
)
RequestContextHolder
.
getRequestAttributes
())
.
getRequest
();
(
HttpServletRequest
)
ShiroHttpServletRequest
.
getRequest
();
String
toke
n
=
request
.
getHeader
(
AUTHORIZATION
);
if
(
StringUtils
.
isBlank
(
toke
n
))
{
String
authorizatio
n
=
request
.
getHeader
(
AUTHORIZATION
);
if
(
StringUtils
.
isBlank
(
authorizatio
n
))
{
throw
new
AuthenticationException
(
"token不能为空"
);
}
// 校验Signature是否完整 合规
if
(!
authorization
.
startsWith
(
"WECLOUD-IM AppKey"
))
{
throw
new
AuthenticationException
(
"token错误"
);
}
if
(!
authorization
.
contains
(
", Signature:"
))
{
throw
new
AuthenticationException
(
"token 未包含签名信息"
);
}
String
appKey
=
getAppKeyFromAuthorization
(
authorization
);
String
clientSignature
=
getSignatureFromAuthorization
(
authorization
);
return
null
;
// 校验通过 获取并校验Application信息
Application
application
=
applicationService
.
getApplication
(
appKey
);
if
(
application
==
null
)
{
throw
new
AuthenticationException
(
"application does not exist"
);
}
if
(!
application
.
isActive
())
{
throw
new
AuthenticationException
(
"application is unavailable"
);
}
Long
appId
=
application
.
getId
();
String
appSecret
=
application
.
getAppSecret
();
SignatureChecker
.
check
(
request
,
clientSignature
,
appSecret
);
// 构建SignatureAuthToken
return
new
SignatureAuthToken
(
appKey
,
appId
);
}
@Override
protected
boolean
isAccessAllowed
(
ServletRequest
request
,
ServletResponse
response
,
Object
mappedValue
)
{
String
url
=
WebUtils
.
toHttp
(
request
).
getRequestURI
();
log
.
info
(
"isAccessAllowed url:{}"
,
url
);
if
(
this
.
isLoginRequest
(
request
,
response
))
{
return
true
;
}
boolean
allowed
=
false
;
try
{
allowed
=
executeLogin
(
request
,
response
);
}
catch
(
IllegalStateException
e
)
{
//not found any token
log
.
error
(
"Token不能为空"
,
e
);
}
catch
(
Exception
e
)
{
log
.
error
(
"访问错误"
,
e
);
}
return
true
;
}
@Override
protected
boolean
onAccessDenied
(
ServletRequest
servletRequest
,
ServletResponse
servletResponse
)
throws
Exception
{
return
false
;
}
private
String
getAppKeyFromAuthorization
(
String
authorization
)
{
// 处理token
String
[]
tokenInfo
=
authorization
.
split
(
","
);
// appkey 格式是固定的,直接替换
return
tokenInfo
[
0
].
replace
(
"WECLOUD-IM AppKey:"
,
""
).
trim
();
}
private
String
getSignatureFromAuthorization
(
String
authorization
)
{
// 处理token
String
[]
tokenInfo
=
authorization
.
split
(
","
);
// 客户端传入的签名信息
return
tokenInfo
[
1
].
replace
(
"Signature:"
,
""
).
trim
();
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignatureAuthRealm.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
import
org.apache.commons.collections4.SetUtils
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.authc.AuthenticationInfo
;
import
org.apache.shiro.authc.AuthenticationToken
;
import
org.apache.shiro.authc.SimpleAuthenticationInfo
;
import
org.apache.shiro.authz.AuthorizationInfo
;
import
org.apache.shiro.authz.SimpleAuthorizationInfo
;
import
org.apache.shiro.realm.AuthorizingRealm
;
import
org.apache.shiro.subject.PrincipalCollection
;
/**
*
* @Author luozh
* @Date 2022年04月15日 17:21
* @Version 1.0
*/
public
class
SignatureAuthRealm
extends
AuthorizingRealm
{
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
SimpleAuthorizationInfo
authorizationInfo
=
new
SimpleAuthorizationInfo
();
// 设置角色
authorizationInfo
.
setRoles
(
SetUtils
.
hashSet
(
"client:all"
));
return
authorizationInfo
;
}
@Override
protected
AuthenticationInfo
doGetAuthenticationInfo
(
AuthenticationToken
authenticationToken
)
throws
AuthenticationException
{
// 校验token
SignatureAuthToken
token
=
(
SignatureAuthToken
)
authenticationToken
;
if
(
token
==
null
)
{
throw
new
AuthenticationException
(
"token不能为空"
);
}
return
new
SimpleAuthenticationInfo
(
token
,
token
.
getCredentials
(),
getName
()
);
}
@Override
public
boolean
supports
(
AuthenticationToken
token
)
{
return
token
instanceof
SignatureAuthToken
;
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignatureAuthToken.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
import
io.geekidea.springbootplus.framework.util.IpUtil
;
import
lombok.Data
;
import
org.apache.shiro.authc.HostAuthenticationToken
;
/**
*
* @Author luozh
* @Date 2022年04月15日 15:19
* @Version 1.0
*/
@Data
public
class
SignatureAuthToken
implements
HostAuthenticationToken
{
/**
* 登录ip
*/
private
String
host
;
/**
* appKey
*/
private
String
appKey
;
/**
* appId
*/
private
Long
appId
;
public
SignatureAuthToken
(
String
appKey
,
Long
appId
)
{
this
.
appKey
=
appKey
;
this
.
appId
=
appId
;
setHost
(
IpUtil
.
getRequestIp
());
}
@Override
public
Object
getPrincipal
()
{
return
appKey
;
}
@Override
public
Object
getCredentials
()
{
return
appKey
;
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/signature/SignatureChecker.java
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
signature
;
import
java.nio.charset.StandardCharsets
;
import
java.util.Collections
;
import
java.util.Enumeration
;
import
java.util.LinkedHashMap
;
...
...
@@ -9,6 +8,7 @@ import java.util.Map;
import
javax.servlet.http.HttpServletRequest
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.springframework.util.CollectionUtils
;
import
com.alibaba.fastjson.JSON
;
...
...
@@ -33,34 +33,57 @@ public class SignatureChecker {
* @Author luozh
* @Date 2022年04月14日 05:32:32
* @param request 请求信息
* @param signature 签名
* @param clientSignature 签名
* @param appSecret app秘钥
* @Return appKey
*/
public
static
String
check
(
HttpServletRequest
request
,
String
signature
)
{
public
static
void
check
(
HttpServletRequest
request
,
String
clientSignature
,
String
appSecret
)
{
// 获取到入参
Map
<
String
,
String
>
params
=
getParameterMap
(
request
);
// 获取请求头
Map
<
String
,
String
>
headers
=
getHeaderMap
(
request
);
// resourcePath
String
resourcePath
=
request
.
getRequestURI
();
// request methos
String
requestMethod
=
request
.
getMethod
();
String
serverSignature
=
SignUtils
.
buildSignature
(
appSecret
,
requestMethod
,
resourcePath
,
headers
,
params
);
if
(!
serverSignature
.
equals
(
clientSignature
))
{
// 返回给用户的response中告诉用户正确的用于验证加密的签名字符串
throw
new
AuthenticationException
(
"token 错误"
);
}
}
public
static
Map
<
String
,
String
>
getHeaderMap
(
HttpServletRequest
servletRequest
)
{
Map
<
String
,
String
>
headerMap
=
new
LinkedHashMap
<>();
Enumeration
<
String
>
names
=
servletRequest
.
getHeaderNames
();
while
(
names
.
hasMoreElements
())
{
String
key
=
names
.
nextElement
();
headerMap
.
put
(
key
,
servletRequest
.
getHeader
(
key
));
}
return
""
;
return
headerMap
;
}
/**
* 获取请求入参
*
* @param
r
equest
* @param
servletR
equest
* @return
*/
public
static
Map
<
String
,
Object
>
getParameterMap
(
HttpServletRequest
request
)
{
Map
<
String
,
Object
>
paramMap
=
new
LinkedHashMap
<>();
if
(
request
instanceof
RequestWrapper
)
{
RequestWrapper
requestWrapper
=
(
RequestWrapper
)
request
;
Map
<
String
,
Object
>
body
=
getParameterMap
(
requestWrapper
.
getRequestBody
());
public
static
Map
<
String
,
String
>
getParameterMap
(
HttpServletRequest
servletRequest
)
{
Map
<
String
,
String
>
paramMap
=
new
LinkedHashMap
<>();
if
(
servletRequest
instanceof
RequestWrapper
)
{
RequestWrapper
requestWrapper
=
(
RequestWrapper
)
servletRequest
;
Map
<
String
,
String
>
body
=
getParameterMap
(
requestWrapper
.
getBody
());
if
(!
CollectionUtils
.
isEmpty
(
body
))
{
paramMap
.
putAll
(
body
);
}
}
Enumeration
<
String
>
names
=
r
equest
.
getParameterNames
();
Enumeration
<
String
>
names
=
servletR
equest
.
getParameterNames
();
while
(
names
.
hasMoreElements
())
{
String
key
=
names
.
nextElement
();
paramMap
.
put
(
key
,
r
equest
.
getParameter
(
key
));
paramMap
.
put
(
key
,
servletR
equest
.
getParameter
(
key
));
}
return
paramMap
;
...
...
@@ -72,11 +95,11 @@ public class SignatureChecker {
* @param params
* @return
*/
public
static
Map
<
String
,
Object
>
getParameterMap
(
byte
[]
params
)
{
public
static
Map
<
String
,
String
>
getParameterMap
(
String
params
)
{
try
{
return
JSON
.
parseObject
(
new
String
(
params
)
,
Map
.
class
);
return
(
Map
<
String
,
String
>)
JSON
.
parseObject
(
params
,
Map
.
class
);
}
catch
(
Exception
e
)
{
return
convertParameterToMap
(
new
String
(
params
,
StandardCharsets
.
UTF_8
)
);
return
convertParameterToMap
(
params
);
}
}
...
...
@@ -87,11 +110,11 @@ public class SignatureChecker {
* @param param
* @return
*/
public
static
Map
<
String
,
Object
>
convertParameterToMap
(
String
param
)
{
public
static
Map
<
String
,
String
>
convertParameterToMap
(
String
param
)
{
if
(
StringUtils
.
isEmpty
(
param
))
{
return
Collections
.
emptyMap
();
}
Map
<
String
,
Object
>
pMap
=
Maps
.
newLinkedHashMap
();
Map
<
String
,
String
>
pMap
=
Maps
.
newLinkedHashMap
();
String
[]
pArray
=
StringUtils
.
split
(
param
,
"&"
);
for
(
int
i
=
0
;
i
<
pArray
.
length
;
i
++)
{
String
[]
array
=
StringUtils
.
split
(
pArray
[
i
],
"="
);
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/util/JwtUtil.java
View file @
6a1ec9f7
...
...
@@ -16,23 +16,25 @@
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
util
;
import
com.alibaba.fastjson.JSON
;
import
com.auth0.jwt.JWT
;
import
com.auth0.jwt.JWTVerifier
;
import
com.auth0.jwt.algorithms.Algorithm
;
import
com.auth0.jwt.interfaces.DecodedJWT
;
import
io.geekidea.springbootplus.config.constant.CommonConstant
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.util.UUIDUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
java.time.Duration
;
import
java.util.Date
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.time.DateUtils
;
import
org.apache.shiro.SecurityUtils
;
import
org.springframework.stereotype.Component
;
import
java.time.Duration
;
import
java.util.Date
;
import
com.alibaba.fastjson.JSON
;
import
com.auth0.jwt.JWT
;
import
com.auth0.jwt.JWTVerifier
;
import
com.auth0.jwt.algorithms.Algorithm
;
import
com.auth0.jwt.interfaces.DecodedJWT
;
/**
* JWT工具类
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/util/SecurityUtils.java
0 → 100644
View file @
6a1ec9f7
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
util
;
import
io.geekidea.springbootplus.framework.shiro.signature.SignatureAuthToken
;
/**
*
* @Author luozh
* @Date 2022年04月15日 19:57
* @Version 1.0
*/
public
class
SecurityUtils
{
/**
* 获取当前签名token
* @Author luozh
* @Date 2022年04月15日 07:53:54
* @param
* @Return 签名token
*/
public
static
SignatureAuthToken
getCurrentSignatureAuthToken
()
{
return
(
SignatureAuthToken
)
org
.
apache
.
shiro
.
SecurityUtils
.
getSubject
().
getPrincipal
();
}
/**
* 获取当前请求appId
* @Author luozh
* @Date 2022年04月15日 07:58:36
* @param
* @Return
*/
public
static
Long
getCurrentAppId
()
{
return
getCurrentSignatureAuthToken
().
getAppId
();
}
/**
* 获取当前请求appKey
* @Author luozh
* @Date 2022年04月15日 07:58:56
* @param
* @Return
*/
public
static
String
getCurrentAppKey
()
{
return
getCurrentSignatureAuthToken
().
getAppKey
();
}
}
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