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
543097ed
Commit
543097ed
authored
Sep 25, 2020
by
hewei
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'double_realm_test' into 'master'
初步完成shiro See merge request hewei/Jumeirah!3
parents
19573744
0edcf9b6
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
1150 additions
and
244 deletions
+1150
-244
README.md
+14
-1
api-app/src/main/java/com/jumeirah/api/app/controller/AppHelloWorldController.java
+23
-5
api-app/src/main/java/com/jumeirah/api/app/controller/AppUserController.java
+13
-6
bootstrap/src/main/java/io/geekidea/springbootplus/config/ShiroConfig.java
+59
-21
bootstrap/src/main/java/io/geekidea/springbootplus/config/Swagger2Config.java
+75
-2
common/src/main/java/com/jumeirah/common/service/AppUserService.java
+3
-0
common/src/main/java/com/jumeirah/common/service/impl/AppUserServiceImpl.java
+112
-0
common/src/main/java/com/jumeirah/common/service/impl/SysLoginServiceImpl.java
+8
-10
config/src/main/java/io/geekidea/springbootplus/config/constant/AppLoginRedisKey.java
+61
-0
config/src/main/java/io/geekidea/springbootplus/config/constant/CommonConstant.java
+2
-2
config/src/main/java/io/geekidea/springbootplus/config/constant/CommonRedisKey.java
+1
-31
config/src/main/java/io/geekidea/springbootplus/config/constant/MerchantLoginRedisKey.java
+59
-0
config/src/main/java/io/geekidea/springbootplus/config/constant/SysLoginRedisKey.java
+59
-0
config/src/main/resources/config/application.yml
+3
-3
framework/src/main/java/io/geekidea/springbootplus/framework/log/aop/BaseLogAop.java
+1
-2
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/AppLoginRedisService.java
+1
-1
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/MerchantLoginRedisService.java
+98
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/SysLoginRedisService.java
+98
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/impl/AppLoginRedisServiceImpl.java
+176
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/impl/MerchantLoginRedisServiceImpl.java
+175
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/impl/SysLoginRedisServiceImpl.java
+17
-17
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/JwtFilter.java
+23
-8
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/JwtRealmSystem.java
+0
-104
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/JwtToken.java
+4
-1
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/realm/JwtRealmAppUser.java
+15
-7
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/realm/JwtRealmMerchant.java
+15
-6
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/realm/JwtRealmSystem.java
+15
-10
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/service/impl/ShiroLoginServiceImpl.java
+5
-5
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/util/JwtUtil.java
+7
-0
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/vo/JwtTokenRedisVo.java
+3
-0
framework/src/main/java/io/geekidea/springbootplus/framework/util/LoginUtil.java
+5
-2
No files found.
README.md
View file @
543097ed
...
@@ -69,11 +69,24 @@ api-system api-app api-merchant
...
@@ -69,11 +69,24 @@ api-system api-app api-merchant
注册业务逻辑要调用common模块中的service去操作
注册业务逻辑要调用common模块中的service去操作
## swagger文档
http://127.0.0.1:8889/api/doc.html#/home
左上角可以切换到不同的模块
## 权限验证
## 权限验证
使用shiro框架
Shiro 的核心:
Subject(主体): 用于记录当前的操作用户,Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授权,而subject是通过SecurityManager安全管理器进行认证授权
SecurityManager(安全管理器):对Subject 进行管理,他是shiro的核心SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口。
Authenticator(认证器):对用户身份进行认证
Authorizer(授权器):用户通过认证后,来判断时候拥有该权限
realm:获取用户权限数据
sessionManager(会话管理):shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。
CacheManager(缓存管理器):将用户权限数据存储在缓存,这样可以提高性能。
authc:所有url都必须认证通过才可以访问;
authc:所有url都必须认证通过才可以访问;
...
...
api-app/src/main/java/com/jumeirah/api/app/controller/AppHelloWorldController.java
View file @
543097ed
...
@@ -6,6 +6,7 @@ import io.geekidea.springbootplus.framework.log.annotation.OperationLog;
...
@@ -6,6 +6,7 @@ import io.geekidea.springbootplus.framework.log.annotation.OperationLog;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.shiro.authz.annotation.RequiresRoles
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
...
@@ -31,7 +32,7 @@ public class AppHelloWorldController {
...
@@ -31,7 +32,7 @@ public class AppHelloWorldController {
*/
*/
@GetMapping
(
value
=
"/world"
)
@GetMapping
(
value
=
"/world"
)
@OperationLog
(
name
=
"helloWorld"
)
@OperationLog
(
name
=
"helloWorld"
)
@ApiOperation
(
value
=
"
Hello
World"
,
response
=
String
.
class
)
@ApiOperation
(
value
=
"
hello
World"
,
response
=
String
.
class
)
public
ApiResult
<
String
>
helloWorld
()
throws
IOException
{
public
ApiResult
<
String
>
helloWorld
()
throws
IOException
{
log
.
debug
(
"Hello World...app"
);
log
.
debug
(
"Hello World...app"
);
return
ApiResult
.
ok
(
"Hello World app"
);
return
ApiResult
.
ok
(
"Hello World app"
);
...
@@ -39,16 +40,33 @@ public class AppHelloWorldController {
...
@@ -39,16 +40,33 @@ public class AppHelloWorldController {
@GetMapping
(
value
=
"/needRole"
)
@GetMapping
(
value
=
"/needRole"
)
@OperationLog
(
name
=
"
helloWorld
"
)
@OperationLog
(
name
=
"
needRole
"
)
@ApiOperation
(
value
=
"
Hello World
"
,
response
=
String
.
class
)
@ApiOperation
(
value
=
"
needRole
"
,
response
=
String
.
class
)
public
ApiResult
<
String
>
needRole
()
throws
IOException
{
public
ApiResult
<
String
>
needRole
()
throws
IOException
{
log
.
debug
(
"Hello World...app"
);
log
.
debug
(
"Hello World...app"
);
return
ApiResult
.
ok
(
"Hello World app"
);
return
ApiResult
.
ok
(
"Hello World app"
);
}
}
@GetMapping
(
value
=
"/needRoleAdmin"
)
@OperationLog
(
name
=
"needRoleAdmin"
)
@ApiOperation
(
value
=
"needRoleAdmin"
,
response
=
String
.
class
)
@RequiresRoles
(
"app:admin"
)
public
ApiResult
<
String
>
needRoleAdmin
()
throws
IOException
{
log
.
debug
(
"Hello World...app"
);
return
ApiResult
.
ok
(
"Hello World needRoleAdmin"
);
}
@GetMapping
(
value
=
"/needRoleAll"
)
@OperationLog
(
name
=
"needRoleAll"
)
@ApiOperation
(
value
=
"needRoleAll"
,
response
=
String
.
class
)
@RequiresRoles
(
"app:all"
)
public
ApiResult
<
String
>
needRoleAll
()
throws
IOException
{
log
.
debug
(
"Hello World...app"
);
return
ApiResult
.
ok
(
"Hello World needRoleAll"
);
}
@GetMapping
(
value
=
"/noRole"
)
@GetMapping
(
value
=
"/noRole"
)
@OperationLog
(
name
=
"
helloWorld
"
)
@OperationLog
(
name
=
"
noRole
"
)
@ApiOperation
(
value
=
"
Hello World
"
,
response
=
String
.
class
)
@ApiOperation
(
value
=
"
noRole
"
,
response
=
String
.
class
)
public
ApiResult
<
String
>
noRole
()
throws
IOException
{
public
ApiResult
<
String
>
noRole
()
throws
IOException
{
log
.
debug
(
"Hello World...app"
);
log
.
debug
(
"Hello World...app"
);
return
ApiResult
.
ok
(
"Hello World app noRole"
);
return
ApiResult
.
ok
(
"Hello World app noRole"
);
...
...
api-app/src/main/java/com/jumeirah/api/app/controller/AppUserController.java
View file @
543097ed
...
@@ -2,6 +2,7 @@ package com.jumeirah.api.app.controller;
...
@@ -2,6 +2,7 @@ package com.jumeirah.api.app.controller;
import
com.jumeirah.common.entity.AppUser
;
import
com.jumeirah.common.entity.AppUser
;
import
com.jumeirah.common.param.AppUserPageParam
;
import
com.jumeirah.common.param.AppUserPageParam
;
import
com.jumeirah.common.param.LoginParam
;
import
com.jumeirah.common.param.RegisterParam
;
import
com.jumeirah.common.param.RegisterParam
;
import
com.jumeirah.common.service.AppUserService
;
import
com.jumeirah.common.service.AppUserService
;
import
com.jumeirah.common.vo.AppUserQueryVo
;
import
com.jumeirah.common.vo.AppUserQueryVo
;
...
@@ -38,7 +39,7 @@ import javax.servlet.http.HttpServletResponse;
...
@@ -38,7 +39,7 @@ import javax.servlet.http.HttpServletResponse;
@Slf4j
@Slf4j
@RestController
@RestController
//@Module("api-app")
//@Module("api-app")
@Api
(
value
=
"用户API"
,
tags
=
{
"APP相关"
})
@Api
(
value
=
"用户API"
,
tags
=
{
"APP
用户
相关"
})
@RequestMapping
(
"/app/user/"
)
@RequestMapping
(
"/app/user/"
)
public
class
AppUserController
extends
BaseController
{
public
class
AppUserController
extends
BaseController
{
...
@@ -106,14 +107,20 @@ public class AppUserController extends BaseController {
...
@@ -106,14 +107,20 @@ public class AppUserController extends BaseController {
@ApiOperation
(
value
=
"注册"
,
notes
=
"web用户注册"
,
response
=
LoginSysUserTokenVo
.
class
)
@ApiOperation
(
value
=
"注册"
,
notes
=
"web用户注册"
,
response
=
LoginSysUserTokenVo
.
class
)
public
ApiResult
<
LoginSysUserTokenVo
>
register
(
@Validated
@RequestBody
RegisterParam
registerParam
,
HttpServletResponse
response
,
@RequestHeader
(
required
=
false
)
String
language
)
throws
Exception
{
public
ApiResult
<
LoginSysUserTokenVo
>
register
(
@Validated
@RequestBody
RegisterParam
registerParam
,
HttpServletResponse
response
,
@RequestHeader
(
required
=
false
)
String
language
)
throws
Exception
{
return
appUserService
.
register
(
registerParam
,
language
);
return
appUserService
.
register
(
registerParam
,
language
);
}
}
@PostMapping
(
"/
phoneL
ogin"
)
@PostMapping
(
"/
l
ogin"
)
@OperationLogIgnore
@OperationLogIgnore
@ApiOperation
(
value
=
"
手机号登陆"
,
notes
=
"手机号登陆
"
,
response
=
LoginSysUserTokenVo
.
class
)
@ApiOperation
(
value
=
"
登录"
,
notes
=
"系统用户登录
"
,
response
=
LoginSysUserTokenVo
.
class
)
public
ApiResult
<
LoginSysUserTokenVo
>
phoneLogin
(
@Validated
@RequestBody
RegisterParam
register
Param
,
HttpServletResponse
response
,
@RequestHeader
(
required
=
false
)
String
language
)
throws
Exception
{
public
ApiResult
<
LoginSysUserTokenVo
>
login
(
@Validated
@RequestBody
LoginParam
login
Param
,
HttpServletResponse
response
,
@RequestHeader
(
required
=
false
)
String
language
)
throws
Exception
{
return
appUserService
.
register
(
register
Param
,
language
);
return
appUserService
.
login
(
login
Param
,
language
);
}
}
// @PostMapping("/phoneLogin")
// @OperationLogIgnore
// @ApiOperation(value = "手机号登陆", notes = "手机号登陆", response = LoginSysUserTokenVo.class)
// public ApiResult<LoginSysUserTokenVo> phoneLogin(@Validated @RequestBody RegisterParam registerParam, HttpServletResponse response, @RequestHeader(required = false) String language) throws Exception {
// return appUserService.register(registerParam, language);
// }
}
}
bootstrap/src/main/java/io/geekidea/springbootplus/config/ShiroConfig.java
View file @
543097ed
...
@@ -20,11 +20,15 @@ import com.alibaba.fastjson.JSON;
...
@@ -20,11 +20,15 @@ import com.alibaba.fastjson.JSON;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.ShiroPermissionProperties
;
import
io.geekidea.springbootplus.config.properties.ShiroPermissionProperties
;
import
io.geekidea.springbootplus.config.properties.ShiroProperties
;
import
io.geekidea.springbootplus.config.properties.ShiroProperties
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.AppLoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.MerchantLoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.SysLoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.exception.ShiroConfigException
;
import
io.geekidea.springbootplus.framework.shiro.exception.ShiroConfigException
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtCredentialsMatcher
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtCredentialsMatcher
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtFilter
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtFilter
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtRealm
;
import
io.geekidea.springbootplus.framework.shiro.jwt.realm.JwtRealmAppUser
;
import
io.geekidea.springbootplus.framework.shiro.jwt.realm.JwtRealmMerchant
;
import
io.geekidea.springbootplus.framework.shiro.jwt.realm.JwtRealmSystem
;
import
io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService
;
import
io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService
;
import
io.geekidea.springbootplus.framework.util.IniUtil
;
import
io.geekidea.springbootplus.framework.util.IniUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
...
@@ -41,6 +45,7 @@ import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
...
@@ -41,6 +45,7 @@ import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import
org.apache.shiro.mgt.DefaultSubjectDAO
;
import
org.apache.shiro.mgt.DefaultSubjectDAO
;
import
org.apache.shiro.mgt.SecurityManager
;
import
org.apache.shiro.mgt.SecurityManager
;
import
org.apache.shiro.mgt.SessionStorageEvaluator
;
import
org.apache.shiro.mgt.SessionStorageEvaluator
;
import
org.apache.shiro.realm.Realm
;
import
org.apache.shiro.spring.LifecycleBeanPostProcessor
;
import
org.apache.shiro.spring.LifecycleBeanPostProcessor
;
import
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
;
import
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
;
import
org.apache.shiro.spring.web.ShiroFilterFactoryBean
;
import
org.apache.shiro.spring.web.ShiroFilterFactoryBean
;
...
@@ -51,6 +56,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
...
@@ -51,6 +56,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import
org.springframework.boot.web.servlet.FilterRegistrationBean
;
import
org.springframework.boot.web.servlet.FilterRegistrationBean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.web.filter.DelegatingFilterProxy
;
import
org.springframework.web.filter.DelegatingFilterProxy
;
import
javax.servlet.DispatcherType
;
import
javax.servlet.DispatcherType
;
...
@@ -103,13 +109,37 @@ public class ShiroConfig {
...
@@ -103,13 +109,37 @@ public class ShiroConfig {
}
}
/**
/**
*
JWT数据源验证
*
系统的用户及权限数据
*
*
* @return
* @return
*/
*/
@Bean
@Bean
public
JwtRealm
jwtRealm
(
LoginRedisService
loginRedisService
)
{
public
JwtRealmSystem
jwtRealmSystem
(
SysLoginRedisService
loginRedisService
)
{
JwtRealm
jwtRealm
=
new
JwtRealm
(
loginRedisService
);
JwtRealmSystem
jwtRealm
=
new
JwtRealmSystem
(
loginRedisService
);
jwtRealm
.
setCachingEnabled
(
false
);
jwtRealm
.
setCredentialsMatcher
(
credentialsMatcher
());
return
jwtRealm
;
}
/**
* app的用户及权限数据
*/
@Bean
public
JwtRealmAppUser
jwtRealmAppUser
(
AppLoginRedisService
appLoginRedisService
)
{
JwtRealmAppUser
jwtRealm
=
new
JwtRealmAppUser
(
appLoginRedisService
);
jwtRealm
.
setCachingEnabled
(
false
);
jwtRealm
.
setCredentialsMatcher
(
credentialsMatcher
());
return
jwtRealm
;
}
/**
* 商家的用户及权限数据
*/
@Bean
public
JwtRealmMerchant
jwtRealmMerchant
(
MerchantLoginRedisService
merchantLoginRedisService
)
{
JwtRealmMerchant
jwtRealm
=
new
JwtRealmMerchant
(
merchantLoginRedisService
);
jwtRealm
.
setCachingEnabled
(
false
);
jwtRealm
.
setCachingEnabled
(
false
);
jwtRealm
.
setCredentialsMatcher
(
credentialsMatcher
());
jwtRealm
.
setCredentialsMatcher
(
credentialsMatcher
());
return
jwtRealm
;
return
jwtRealm
;
...
@@ -118,8 +148,6 @@ public class ShiroConfig {
...
@@ -118,8 +148,6 @@ public class ShiroConfig {
/**
/**
* subject不存储到Session中
* subject不存储到Session中
*
* @return
*/
*/
@Bean
@Bean
public
SessionStorageEvaluator
sessionStorageEvaluator
()
{
public
SessionStorageEvaluator
sessionStorageEvaluator
()
{
...
@@ -142,14 +170,20 @@ public class ShiroConfig {
...
@@ -142,14 +170,20 @@ public class ShiroConfig {
/**
/**
* 安全管理器配置
* 安全管理器配置
*
* @return
*/
*/
@Bean
@Bean
public
SecurityManager
securityManager
(
LoginRedisService
l
oginRedisService
)
{
public
SecurityManager
securityManager
(
SysLoginRedisService
sysLoginRedisService
,
AppLoginRedisService
appLoginRedisService
,
MerchantLoginRedisService
merchantL
oginRedisService
)
{
DefaultWebSecurityManager
securityManager
=
new
DefaultWebSecurityManager
();
DefaultWebSecurityManager
securityManager
=
new
DefaultWebSecurityManager
();
// 设置多个realms
List
<
Realm
>
realms
=
new
ArrayList
<>();
realms
.
add
(
jwtRealmSystem
(
sysLoginRedisService
));
realms
.
add
(
jwtRealmAppUser
(
appLoginRedisService
));
realms
.
add
(
jwtRealmMerchant
(
merchantLoginRedisService
));
// 数据连接器
// 数据连接器
securityManager
.
setRealm
(
jwtRealm
(
loginRedisService
));
securityManager
.
setRealms
(
realms
);
// 设置session存储方式: 不使用sessionId保存
// 设置session存储方式: 不使用sessionId保存
securityManager
.
setSubjectDAO
(
subjectDAO
());
securityManager
.
setSubjectDAO
(
subjectDAO
());
SecurityUtils
.
setSecurityManager
(
securityManager
);
SecurityUtils
.
setSecurityManager
(
securityManager
);
...
@@ -160,7 +194,7 @@ public class ShiroConfig {
...
@@ -160,7 +194,7 @@ public class ShiroConfig {
* ShiroFilterFactoryBean过滤器配置
* ShiroFilterFactoryBean过滤器配置
*
*
* @param securityManager
* @param securityManager
* @param
l
oginRedisService
* @param
sysL
oginRedisService
* @param shiroProperties
* @param shiroProperties
* @param jwtProperties
* @param jwtProperties
* @return
* @return
...
@@ -168,15 +202,16 @@ public class ShiroConfig {
...
@@ -168,15 +202,16 @@ public class ShiroConfig {
@Bean
(
SHIRO_FILTER_NAME
)
@Bean
(
SHIRO_FILTER_NAME
)
public
ShiroFilterFactoryBean
shiroFilterFactoryBean
(
SecurityManager
securityManager
,
public
ShiroFilterFactoryBean
shiroFilterFactoryBean
(
SecurityManager
securityManager
,
ShiroLoginService
shiroLoginService
,
ShiroLoginService
shiroLoginService
,
LoginRedisService
l
oginRedisService
,
SysLoginRedisService
sysL
oginRedisService
,
ShiroProperties
shiroProperties
,
ShiroProperties
shiroProperties
,
JwtProperties
jwtProperties
)
{
JwtProperties
jwtProperties
,
RedisTemplate
redisTemplate
)
{
ShiroFilterFactoryBean
shiroFilterFactoryBean
=
new
ShiroFilterFactoryBean
();
ShiroFilterFactoryBean
shiroFilterFactoryBean
=
new
ShiroFilterFactoryBean
();
// 设置安全管理器
// 设置安全管理器
shiroFilterFactoryBean
.
setSecurityManager
(
securityManager
);
shiroFilterFactoryBean
.
setSecurityManager
(
securityManager
);
// 设置过滤器
// 设置过滤器
Map
<
String
,
Filter
>
filterMap
=
getFilterMap
(
shiroLoginService
,
loginRedisService
,
jwtProperties
);
Map
<
String
,
Filter
>
filterMap
=
getFilterMap
(
shiroLoginService
,
sysLoginRedisService
,
jwtProperties
,
redisTemplate
);
shiroFilterFactoryBean
.
setFilters
(
filterMap
);
shiroFilterFactoryBean
.
setFilters
(
filterMap
);
// 设置过滤器顺序
// 设置过滤器顺序
Map
<
String
,
String
>
filterChainMap
=
getFilterChainDefinitionMap
(
shiroProperties
);
Map
<
String
,
String
>
filterChainMap
=
getFilterChainDefinitionMap
(
shiroProperties
);
...
@@ -191,10 +226,11 @@ public class ShiroConfig {
...
@@ -191,10 +226,11 @@ public class ShiroConfig {
* @return
* @return
*/
*/
private
Map
<
String
,
Filter
>
getFilterMap
(
ShiroLoginService
shiroLoginService
,
private
Map
<
String
,
Filter
>
getFilterMap
(
ShiroLoginService
shiroLoginService
,
LoginRedisService
loginRedisService
,
SysLoginRedisService
loginRedisService
,
JwtProperties
jwtProperties
)
{
JwtProperties
jwtProperties
,
RedisTemplate
redisTemplate
)
{
Map
<
String
,
Filter
>
filterMap
=
new
LinkedHashMap
<>();
Map
<
String
,
Filter
>
filterMap
=
new
LinkedHashMap
<>();
filterMap
.
put
(
JWT_FILTER_NAME
,
new
JwtFilter
(
shiroLoginService
,
loginRedisService
,
jwtProperties
));
filterMap
.
put
(
JWT_FILTER_NAME
,
new
JwtFilter
(
shiroLoginService
,
loginRedisService
,
jwtProperties
,
redisTemplate
));
return
filterMap
;
return
filterMap
;
}
}
...
@@ -314,13 +350,15 @@ public class ShiroConfig {
...
@@ -314,13 +350,15 @@ public class ShiroConfig {
/**
/**
* 认证模式
* 认证模式
*
*
* @param
l
oginRedisService
* @param
sysL
oginRedisService
* @return
* @return
*/
*/
@Bean
@Bean
public
Authenticator
authenticator
(
LoginRedisService
l
oginRedisService
)
{
public
Authenticator
authenticator
(
SysLoginRedisService
sysL
oginRedisService
)
{
ModularRealmAuthenticator
authenticator
=
new
ModularRealmAuthenticator
();
ModularRealmAuthenticator
authenticator
=
new
ModularRealmAuthenticator
();
authenticator
.
setRealms
(
Arrays
.
asList
(
jwtRealm
(
loginRedisService
)));
List
<
Realm
>
realms
=
new
ArrayList
<>();
realms
.
add
(
jwtRealmSystem
(
sysLoginRedisService
));
authenticator
.
setRealms
(
realms
);
// 认证策略: 第一个成功
// 认证策略: 第一个成功
authenticator
.
setAuthenticationStrategy
(
new
FirstSuccessfulStrategy
());
authenticator
.
setAuthenticationStrategy
(
new
FirstSuccessfulStrategy
());
return
authenticator
;
return
authenticator
;
...
...
bootstrap/src/main/java/io/geekidea/springbootplus/config/Swagger2Config.java
View file @
543097ed
...
@@ -72,6 +72,7 @@ import static springfox.documentation.swagger.schema.ApiModelProperties.findApiM
...
@@ -72,6 +72,7 @@ import static springfox.documentation.swagger.schema.ApiModelProperties.findApiM
/**
/**
* Swagger2全局配置
* Swagger2全局配置
* 分组教程 https://sns.bladex.vip/q-342.html
*
*
* @author geekidea
* @author geekidea
* @date 2020/3/21
* @date 2020/3/21
...
@@ -128,12 +129,83 @@ public class Swagger2Config {
...
@@ -128,12 +129,83 @@ public class Swagger2Config {
return
Optional
.
fromNullable
(
input
.
declaringClass
());
return
Optional
.
fromNullable
(
input
.
declaringClass
());
}
}
// @Bean
// public Docket createRestApi() {
// // 获取需要扫描的包
// String[] basePackages = getBasePackages();
// ApiSelectorBuilder apiSelectorBuilder = new Docket(DocumentationType.SWAGGER_2)
// .apiInfo(apiInfo("默认", "1.0"))
// .select();
// // 如果扫描的包为空,则默认扫描类上有@Api注解的类
// if (ArrayUtils.isEmpty(basePackages)) {
// apiSelectorBuilder.apis(RequestHandlerSelectors.withClassAnnotation(Api.class));
// } else {
// // 扫描指定的包
// apiSelectorBuilder.apis(basePackage(basePackages));
// }
// Docket docket = apiSelectorBuilder.paths(PathSelectors.any())
// .build()
// .enable(swaggerProperties.isEnable())
// .ignoredParameterTypes(ignoredParameterTypes)
// .globalOperationParameters(getParameters());
// return docket;
// }
@Bean
public
Docket
restAppApi
()
{
// 获取需要扫描的包
String
[]
basePackages
=
{
"com.jumeirah.api.app.controller"
};
ApiSelectorBuilder
apiSelectorBuilder
=
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
groupName
(
"app"
)
.
select
();
// 如果扫描的包为空,则默认扫描类上有@Api注解的类
if
(
ArrayUtils
.
isEmpty
(
basePackages
))
{
apiSelectorBuilder
.
apis
(
RequestHandlerSelectors
.
withClassAnnotation
(
Api
.
class
));
}
else
{
// 扫描指定的包
apiSelectorBuilder
.
apis
(
basePackage
(
basePackages
));
}
Docket
docket
=
apiSelectorBuilder
.
paths
(
PathSelectors
.
any
())
.
build
()
.
enable
(
swaggerProperties
.
isEnable
())
.
ignoredParameterTypes
(
ignoredParameterTypes
)
.
globalOperationParameters
(
getParameters
());
return
docket
;
}
@Bean
@Bean
public
Docket
createRest
Api
()
{
public
Docket
restSys
Api
()
{
// 获取需要扫描的包
// 获取需要扫描的包
String
[]
basePackages
=
getBasePackages
()
;
String
[]
basePackages
=
{
"com.jumeirah.api.system.controlle"
}
;
ApiSelectorBuilder
apiSelectorBuilder
=
new
Docket
(
DocumentationType
.
SWAGGER_2
)
ApiSelectorBuilder
apiSelectorBuilder
=
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
apiInfo
(
apiInfo
())
.
groupName
(
"system"
)
.
select
();
// 如果扫描的包为空,则默认扫描类上有@Api注解的类
if
(
ArrayUtils
.
isEmpty
(
basePackages
))
{
apiSelectorBuilder
.
apis
(
RequestHandlerSelectors
.
withClassAnnotation
(
Api
.
class
));
}
else
{
// 扫描指定的包
apiSelectorBuilder
.
apis
(
basePackage
(
basePackages
));
}
Docket
docket
=
apiSelectorBuilder
.
paths
(
PathSelectors
.
any
())
.
build
()
.
enable
(
swaggerProperties
.
isEnable
())
.
ignoredParameterTypes
(
ignoredParameterTypes
)
.
globalOperationParameters
(
getParameters
());
return
docket
;
}
@Bean
public
Docket
restMerchantApi
()
{
// 获取需要扫描的包
String
[]
basePackages
=
{
"com.jumeirah.api.merchant.controller"
};
ApiSelectorBuilder
apiSelectorBuilder
=
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
apiInfo
(
apiInfo
())
.
groupName
(
"merchant"
)
.
select
();
.
select
();
// 如果扫描的包为空,则默认扫描类上有@Api注解的类
// 如果扫描的包为空,则默认扫描类上有@Api注解的类
if
(
ArrayUtils
.
isEmpty
(
basePackages
))
{
if
(
ArrayUtils
.
isEmpty
(
basePackages
))
{
...
@@ -150,6 +222,7 @@ public class Swagger2Config {
...
@@ -150,6 +222,7 @@ public class Swagger2Config {
return
docket
;
return
docket
;
}
}
/**
/**
* 获取apiInfo
* 获取apiInfo
*
*
...
...
common/src/main/java/com/jumeirah/common/service/AppUserService.java
View file @
543097ed
...
@@ -2,6 +2,7 @@ package com.jumeirah.common.service;
...
@@ -2,6 +2,7 @@ package com.jumeirah.common.service;
import
com.jumeirah.common.entity.AppUser
;
import
com.jumeirah.common.entity.AppUser
;
import
com.jumeirah.common.param.AppUserPageParam
;
import
com.jumeirah.common.param.AppUserPageParam
;
import
com.jumeirah.common.param.LoginParam
;
import
com.jumeirah.common.param.RegisterParam
;
import
com.jumeirah.common.param.RegisterParam
;
import
com.jumeirah.common.vo.AppUserQueryVo
;
import
com.jumeirah.common.vo.AppUserQueryVo
;
import
com.jumeirah.common.vo.LoginSysUserTokenVo
;
import
com.jumeirah.common.vo.LoginSysUserTokenVo
;
...
@@ -18,6 +19,8 @@ import io.geekidea.springbootplus.framework.core.pagination.Paging;
...
@@ -18,6 +19,8 @@ import io.geekidea.springbootplus.framework.core.pagination.Paging;
public
interface
AppUserService
extends
BaseService
<
AppUser
>
{
public
interface
AppUserService
extends
BaseService
<
AppUser
>
{
ApiResult
<
LoginSysUserTokenVo
>
register
(
RegisterParam
registerParam
,
String
language
);
ApiResult
<
LoginSysUserTokenVo
>
register
(
RegisterParam
registerParam
,
String
language
);
ApiResult
<
LoginSysUserTokenVo
>
login
(
LoginParam
loginParam
,
String
language
);
ApiResult
<
LoginSysUserTokenVo
>
phoneLogin
(
RegisterParam
registerParam
,
String
language
);
ApiResult
<
LoginSysUserTokenVo
>
phoneLogin
(
RegisterParam
registerParam
,
String
language
);
...
...
common/src/main/java/com/jumeirah/common/service/impl/AppUserServiceImpl.java
View file @
543097ed
package
com
.
jumeirah
.
common
.
service
.
impl
;
package
com
.
jumeirah
.
common
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.OrderItem
;
import
com.baomidou.mybatisplus.core.metadata.OrderItem
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
com.jumeirah.common.entity.AppUser
;
import
com.jumeirah.common.entity.AppUser
;
import
com.jumeirah.common.enums.StateEnum
;
import
com.jumeirah.common.mapper.AppUserMapper
;
import
com.jumeirah.common.mapper.AppUserMapper
;
import
com.jumeirah.common.param.AppUserPageParam
;
import
com.jumeirah.common.param.AppUserPageParam
;
import
com.jumeirah.common.param.LoginParam
;
import
com.jumeirah.common.param.RegisterParam
;
import
com.jumeirah.common.param.RegisterParam
;
import
com.jumeirah.common.service.AppUserService
;
import
com.jumeirah.common.service.AppUserService
;
import
com.jumeirah.common.vo.AppUserQueryVo
;
import
com.jumeirah.common.vo.AppUserQueryVo
;
import
com.jumeirah.common.vo.LoginSysUserTokenVo
;
import
com.jumeirah.common.vo.LoginSysUserTokenVo
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.SpringBootPlusProperties
;
import
io.geekidea.springbootplus.framework.common.api.ApiCode
;
import
io.geekidea.springbootplus.framework.common.api.ApiResult
;
import
io.geekidea.springbootplus.framework.common.api.ApiResult
;
import
io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl
;
import
io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl
;
import
io.geekidea.springbootplus.framework.core.pagination.PageInfo
;
import
io.geekidea.springbootplus.framework.core.pagination.PageInfo
;
import
io.geekidea.springbootplus.framework.core.pagination.Paging
;
import
io.geekidea.springbootplus.framework.core.pagination.Paging
;
import
io.geekidea.springbootplus.framework.shiro.cache.AppLoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.SaltUtil
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo
;
import
io.geekidea.springbootplus.framework.util.PasswordUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.apache.shiro.SecurityUtils
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.subject.Subject
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.time.Duration
;
import
java.util.concurrent.TimeUnit
;
/**
/**
* APP用户 服务实现类
* APP用户 服务实现类
*
*
...
@@ -30,6 +51,20 @@ import org.springframework.transaction.annotation.Transactional;
...
@@ -30,6 +51,20 @@ import org.springframework.transaction.annotation.Transactional;
public
class
AppUserServiceImpl
extends
BaseServiceImpl
<
AppUserMapper
,
AppUser
>
implements
AppUserService
{
public
class
AppUserServiceImpl
extends
BaseServiceImpl
<
AppUserMapper
,
AppUser
>
implements
AppUserService
{
@Autowired
@Autowired
private
RedisTemplate
redisTemplate
;
@Lazy
@Autowired
private
AppLoginRedisService
appLoginRedisService
;
@Lazy
@Autowired
private
JwtProperties
jwtProperties
;
@Autowired
private
SpringBootPlusProperties
springBootPlusProperties
;
@Autowired
private
AppUserMapper
appUserMapper
;
private
AppUserMapper
appUserMapper
;
@Override
@Override
...
@@ -38,6 +73,83 @@ public class AppUserServiceImpl extends BaseServiceImpl<AppUserMapper, AppUser>
...
@@ -38,6 +73,83 @@ public class AppUserServiceImpl extends BaseServiceImpl<AppUserMapper, AppUser>
}
}
@Override
@Override
public
ApiResult
<
LoginSysUserTokenVo
>
login
(
LoginParam
loginParam
,
String
language
)
{
// 校验验证码
// checkVerifyCode(loginParam.getVerifyToken(), loginParam.getCode());
String
username
=
loginParam
.
getUsername
();
// 从数据库中获取登录用户信息
AppUser
appUser
=
appUserMapper
.
selectOne
(
new
QueryWrapper
<
AppUser
>(
new
AppUser
().
setUsername
(
username
)));
if
(
appUser
==
null
)
{
log
.
error
(
"登录失败,loginParam:{}"
,
loginParam
);
// throw new AuthenticationException("用户名或密码错误");
return
ApiResult
.
fail
(
ApiCode
.
PWD_OR_USERNAME_ERROR
,
language
);
}
if
(
StateEnum
.
DISABLE
.
getCode
().
equals
(
appUser
.
getState
()))
{
throw
new
AuthenticationException
(
"账号已禁用"
);
}
// 实际项目中,前端传过来的密码应先加密
// 原始密码明文:123456
// 原始密码前端加密:sha256(123456)
// 后台加密规则:sha256(sha256(123456) + salt)
String
encryptPassword
=
PasswordUtil
.
encrypt
(
loginParam
.
getPassword
(),
appUser
.
getSalt
());
if
(!
encryptPassword
.
equals
(
appUser
.
getPassword
()))
{
return
ApiResult
.
fail
(
ApiCode
.
PWD_OR_USERNAME_ERROR
,
language
);
}
// 将系统用户对象转换成登录用户对象
LoginSysUserVo
loginSysUserVo
=
new
LoginSysUserVo
();
loginSysUserVo
.
setUsername
(
username
);
// 获取数据库中保存的盐值
String
newSalt
=
SaltUtil
.
getSalt
(
appUser
.
getSalt
(),
jwtProperties
);
// 生成token字符串并返回
Long
expireSecond
=
jwtProperties
.
getExpireSecond
();
String
token
=
JwtUtil
.
generateToken
(
username
,
newSalt
,
Duration
.
ofSeconds
(
expireSecond
));
log
.
debug
(
"token:{}"
,
token
);
// 创建AuthenticationToken
JwtToken
jwtToken
=
JwtToken
.
build
(
token
,
username
,
newSalt
,
expireSecond
,
"app"
);
boolean
enableShiro
=
springBootPlusProperties
.
getShiro
().
isEnable
();
if
(
enableShiro
)
{
// 从SecurityUtils里边创建一个 subject
Subject
subject
=
SecurityUtils
.
getSubject
();
// 执行认证登录
subject
.
login
(
jwtToken
);
}
else
{
log
.
warn
(
"未启用Shiro"
);
}
// 缓存登录信息到Redis
appLoginRedisService
.
cacheLoginInfo
(
jwtToken
,
loginSysUserVo
);
log
.
debug
(
"登录成功,username:{}"
,
username
);
// 缓存登录信息到redis
String
tokenSha256
=
DigestUtils
.
sha256Hex
(
token
);
redisTemplate
.
opsForValue
().
set
(
tokenSha256
,
loginSysUserVo
,
1
,
TimeUnit
.
DAYS
);
// 返回token和登录用户信息对象
LoginSysUserTokenVo
loginSysUserTokenVo
=
new
LoginSysUserTokenVo
();
loginSysUserTokenVo
.
setToken
(
token
);
loginSysUserTokenVo
.
setLoginSysUserVo
(
loginSysUserVo
);
// 设置token响应头
// response.setHeader(JwtTokenUtil.getTokenName(), loginSysUserTokenVo.getToken());
return
ApiResult
.
ok
(
loginSysUserTokenVo
,
language
);
}
@Override
public
ApiResult
<
LoginSysUserTokenVo
>
phoneLogin
(
RegisterParam
registerParam
,
String
language
)
{
public
ApiResult
<
LoginSysUserTokenVo
>
phoneLogin
(
RegisterParam
registerParam
,
String
language
)
{
return
null
;
return
null
;
}
}
...
...
common/src/main/java/com/jumeirah/common/service/impl/SysLoginServiceImpl.java
View file @
543097ed
...
@@ -22,26 +22,26 @@ import com.jumeirah.common.entity.SysDepartment;
...
@@ -22,26 +22,26 @@ import com.jumeirah.common.entity.SysDepartment;
import
com.jumeirah.common.entity.SysRole
;
import
com.jumeirah.common.entity.SysRole
;
import
com.jumeirah.common.entity.SysUser
;
import
com.jumeirah.common.entity.SysUser
;
import
com.jumeirah.common.enums.StateEnum
;
import
com.jumeirah.common.enums.StateEnum
;
import
com.jumeirah.common.exception.VerificationCodeException
;
import
com.jumeirah.common.mapper.SysUserMapper
;
import
com.jumeirah.common.mapper.SysUserMapper
;
import
com.jumeirah.common.param.LoginParam
;
import
com.jumeirah.common.param.LoginParam
;
import
com.jumeirah.common.service.SysDepartmentService
;
import
com.jumeirah.common.service.SysLoginService
;
import
com.jumeirah.common.service.SysRolePermissionService
;
import
com.jumeirah.common.service.SysRoleService
;
import
com.jumeirah.common.vo.LoginSysUserTokenVo
;
import
com.jumeirah.common.vo.LoginSysUserTokenVo
;
import
io.geekidea.springbootplus.config.constant.CommonRedisKey
;
import
io.geekidea.springbootplus.config.constant.CommonRedisKey
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.SpringBootPlusProperties
;
import
io.geekidea.springbootplus.config.properties.SpringBootPlusProperties
;
import
io.geekidea.springbootplus.framework.common.api.ApiCode
;
import
io.geekidea.springbootplus.framework.common.api.ApiCode
;
import
io.geekidea.springbootplus.framework.common.api.ApiResult
;
import
io.geekidea.springbootplus.framework.common.api.ApiResult
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.
Sys
LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.SaltUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.SaltUtil
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo
;
import
io.geekidea.springbootplus.framework.util.PasswordUtil
;
import
io.geekidea.springbootplus.framework.util.PasswordUtil
;
import
com.jumeirah.common.exception.VerificationCodeException
;
import
com.jumeirah.common.service.SysLoginService
;
import
com.jumeirah.common.service.SysDepartmentService
;
import
com.jumeirah.common.service.SysRolePermissionService
;
import
com.jumeirah.common.service.SysRoleService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.Api
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.apache.commons.codec.digest.DigestUtils
;
...
@@ -61,8 +61,6 @@ import java.time.Duration;
...
@@ -61,8 +61,6 @@ import java.time.Duration;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
import
static
io
.
geekidea
.
springbootplus
.
framework
.
common
.
api
.
ApiResult
.
fail
;
/**
/**
* <p>
* <p>
* 登录服务实现类
* 登录服务实现类
...
@@ -78,7 +76,7 @@ public class SysLoginServiceImpl implements SysLoginService {
...
@@ -78,7 +76,7 @@ public class SysLoginServiceImpl implements SysLoginService {
@Lazy
@Lazy
@Autowired
@Autowired
private
LoginRedisService
loginRedisService
;
private
Sys
LoginRedisService
loginRedisService
;
@Lazy
@Lazy
@Autowired
@Autowired
...
@@ -180,7 +178,7 @@ public class SysLoginServiceImpl implements SysLoginService {
...
@@ -180,7 +178,7 @@ public class SysLoginServiceImpl implements SysLoginService {
log
.
debug
(
"token:{}"
,
token
);
log
.
debug
(
"token:{}"
,
token
);
// 创建AuthenticationToken
// 创建AuthenticationToken
JwtToken
jwtToken
=
JwtToken
.
build
(
token
,
username
,
newSalt
,
expireSecond
);
JwtToken
jwtToken
=
JwtToken
.
build
(
token
,
username
,
newSalt
,
expireSecond
,
"sys"
);
boolean
enableShiro
=
springBootPlusProperties
.
getShiro
().
isEnable
();
boolean
enableShiro
=
springBootPlusProperties
.
getShiro
().
isEnable
();
if
(
enableShiro
)
{
if
(
enableShiro
)
{
...
...
config/src/main/java/io/geekidea/springbootplus/config/constant/AppLoginRedisKey.java
0 → 100755
View file @
543097ed
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
io
.
geekidea
.
springbootplus
.
config
.
constant
;
/**
* <p>
* redis key 常量
* </p>
*
* @author geekidea
* @date 2019-05-23
**/
public
interface
AppLoginRedisKey
{
/**
* 登录用户token信息key
* login:token:tokenMd5
*/
String
LOGIN_TOKEN
=
"sys:login:token:%s"
;
/**
* 登录用户信息key
* login:user:username
*/
String
LOGIN_USER
=
"app:login:user:%s"
;
/**
* 登录用户盐值信息key
* login:salt:username
*/
// String LOGIN_SALT = "app:login:salt:%s";
String
LOGIN_SALT
=
"sys:login:salt:%s"
;
/**
* 登录用户username token
* login:user:token:username:token
*/
String
LOGIN_USER_TOKEN
=
"app:login:user:token:%s:%s"
;
/**
* 登录用户下的所有token
* login:user:token:username:*
*/
String
LOGIN_USER_ALL_TOKEN
=
"app:login:user:token:%s:*"
;
}
config/src/main/java/io/geekidea/springbootplus/config/constant/CommonConstant.java
View file @
543097ed
...
@@ -92,9 +92,9 @@ public interface CommonConstant {
...
@@ -92,9 +92,9 @@ public interface CommonConstant {
String
JWT_DEFAULT_SECRET
=
"666666"
;
String
JWT_DEFAULT_SECRET
=
"666666"
;
/**
/**
* JWT 默认过期时间,
3600L
,单位秒
* JWT 默认过期时间,
5184000L = 60天
,单位秒
*/
*/
Long
JWT_DEFAULT_EXPIRE_SECOND
=
36
00L
;
Long
JWT_DEFAULT_EXPIRE_SECOND
=
51840
00L
;
/**
/**
* 默认头像
* 默认头像
...
...
config/src/main/java/io/geekidea/springbootplus/config/constant/CommonRedisKey.java
View file @
543097ed
...
@@ -27,38 +27,8 @@ package io.geekidea.springbootplus.config.constant;
...
@@ -27,38 +27,8 @@ package io.geekidea.springbootplus.config.constant;
public
interface
CommonRedisKey
{
public
interface
CommonRedisKey
{
/**
/**
* 登录用户token信息key
* login:token:tokenMd5
*/
String
LOGIN_TOKEN
=
"login:token:%s"
;
/**
* 登录用户信息key
* login:user:username
*/
String
LOGIN_USER
=
"login:user:%s"
;
/**
* 登录用户盐值信息key
* login:salt:username
*/
String
LOGIN_SALT
=
"login:salt:%s"
;
/**
* 登录用户username token
* login:user:token:username:token
*/
String
LOGIN_USER_TOKEN
=
"login:user:token:%s:%s"
;
/**
* 登录用户下的所有token
* login:user:token:username:*
*/
String
LOGIN_USER_ALL_TOKEN
=
"login:user:token:%s:*"
;
/**
* 验证码
* 验证码
* verify.code:666666
* verify.code:666666
*/
*/
String
VERIFY_CODE
=
"verify.code:%s"
;
String
VERIFY_CODE
=
"verify.
sms
code:%s"
;
}
}
config/src/main/java/io/geekidea/springbootplus/config/constant/MerchantLoginRedisKey.java
0 → 100755
View file @
543097ed
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
io
.
geekidea
.
springbootplus
.
config
.
constant
;
/**
* <p>
* redis key 常量
* </p>
*
* @author geekidea
* @date 2019-05-23
**/
public
interface
MerchantLoginRedisKey
{
/**
* 登录用户token信息key
* login:token:tokenMd5
*/
String
LOGIN_TOKEN
=
"sys:login:token:%s"
;
/**
* 登录用户信息key
* login:user:username
*/
String
LOGIN_USER
=
"mer:login:user:%s"
;
/**
* 登录用户盐值信息key
* login:salt:username
*/
String
LOGIN_SALT
=
"sys:login:salt:%s"
;
/**
* 登录用户username token
* login:user:token:username:token
*/
String
LOGIN_USER_TOKEN
=
"mer:login:user:token:%s:%s"
;
/**
* 登录用户下的所有token
* login:user:token:username:*
*/
String
LOGIN_USER_ALL_TOKEN
=
"mer:login:user:token:%s:*"
;
}
config/src/main/java/io/geekidea/springbootplus/config/constant/SysLoginRedisKey.java
0 → 100755
View file @
543097ed
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
io
.
geekidea
.
springbootplus
.
config
.
constant
;
/**
* <p>
* redis key 常量
* </p>
*
* @author geekidea
* @date 2019-05-23
**/
public
interface
SysLoginRedisKey
{
/**
* 登录用户token信息key
* login:token:tokenMd5
*/
String
LOGIN_TOKEN
=
"sys:login:token:%s"
;
/**
* 登录用户信息key
* login:user:username
*/
String
LOGIN_USER
=
"sys:login:user:%s"
;
/**
* 登录用户盐值信息key
* login:salt:username
*/
String
LOGIN_SALT
=
"sys:login:salt:%s"
;
/**
* 登录用户username token
* login:user:token:username:token
*/
String
LOGIN_USER_TOKEN
=
"sys:login:user:token:%s:%s"
;
/**
* 登录用户下的所有token
* login:user:token:username:*
*/
String
LOGIN_USER_ALL_TOKEN
=
"sys:login:user:token:%s:*"
;
}
config/src/main/resources/config/application.yml
View file @
543097ed
...
@@ -7,7 +7,7 @@ server:
...
@@ -7,7 +7,7 @@ server:
context-path
:
/api
context-path
:
/api
tomcat
:
tomcat
:
max-threads
:
200
max-threads
:
200
min-spare-threads
:
10
min-spare-threads
:
5
uri-encoding
:
UTF-8
uri-encoding
:
UTF-8
############################# 访问路径、端口tomcat end ###############################
############################# 访问路径、端口tomcat end ###############################
...
@@ -183,7 +183,7 @@ spring-boot-plus:
...
@@ -183,7 +183,7 @@ spring-boot-plus:
# 权限配置
# 权限配置
anon
:
anon
:
# 排除登录 注册 登出
# 排除登录 注册 登出
-
/app/user/register,/app/user/phoneLogin,/sys/login,/sys/logout,/sys/register
-
/app/user/register,/app/user/phoneLogin,/
app/user/login,/
sys/login,/sys/logout,/sys/register
# 排除静态资源
# 排除静态资源
-
/static/**,/templates/**
-
/static/**,/templates/**
# 排除Swagger
# 排除Swagger
...
@@ -200,7 +200,7 @@ spring-boot-plus:
...
@@ -200,7 +200,7 @@ spring-boot-plus:
/upload/**=anon
/upload/**=anon
/verificationCode/**=anon
/verificationCode/**=anon
/enum=anon
/enum=anon
# /app/**=authc
/app/*=roles["app:all"]
######################## Spring Shiro end ##########################
######################## Spring Shiro end ##########################
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/log/aop/BaseLogAop.java
View file @
543097ed
...
@@ -45,7 +45,6 @@ import io.geekidea.springbootplus.framework.util.ClientInfoUtil;
...
@@ -45,7 +45,6 @@ import io.geekidea.springbootplus.framework.util.ClientInfoUtil;
import
io.geekidea.springbootplus.framework.util.DateUtil
;
import
io.geekidea.springbootplus.framework.util.DateUtil
;
import
io.geekidea.springbootplus.framework.util.IpUtil
;
import
io.geekidea.springbootplus.framework.util.IpUtil
;
import
io.geekidea.springbootplus.framework.util.Jackson
;
import
io.geekidea.springbootplus.framework.util.Jackson
;
import
io.geekidea.springbootplus.framework.util.LoginUtil
;
import
io.geekidea.springbootplus.framework.util.UUIDUtil
;
import
io.geekidea.springbootplus.framework.util.UUIDUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.apache.commons.codec.digest.DigestUtils
;
...
@@ -824,7 +823,7 @@ public abstract class BaseLogAop {
...
@@ -824,7 +823,7 @@ public abstract class BaseLogAop {
}
}
// 设置当前登录信息
// 设置当前登录信息
sysOperationLog
.
setUserId
(
LoginUtil
.
getUserId
()).
setUserName
(
LoginUtil
.
getUsername
());
//
sysOperationLog.setUserId(LoginUtil.getUserId()).setUserName(LoginUtil.getUsername());
// 设置异常信息
// 设置异常信息
if
(
exception
!=
null
)
{
if
(
exception
!=
null
)
{
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/LoginRedisService.java
→
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/
App
LoginRedisService.java
View file @
543097ed
...
@@ -28,7 +28,7 @@ import io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo;
...
@@ -28,7 +28,7 @@ import io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo;
* @date 2019-09-30
* @date 2019-09-30
* @since 1.3.0.RELEASE
* @since 1.3.0.RELEASE
**/
**/
public
interface
LoginRedisService
{
public
interface
App
LoginRedisService
{
/**
/**
* 缓存登录信息
* 缓存登录信息
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/MerchantLoginRedisService.java
0 → 100755
View file @
543097ed
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
cache
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo
;
/**
* 登录信息Redis缓存操作服务
*
* @author geekidea
* @date 2019-09-30
* @since 1.3.0.RELEASE
**/
public
interface
MerchantLoginRedisService
{
/**
* 缓存登录信息
*
* @param jwtToken
* @param loginSysUserVo
*/
void
cacheLoginInfo
(
JwtToken
jwtToken
,
LoginSysUserVo
loginSysUserVo
);
/**
* 刷新登录信息
*
* @param oldToken
* @param username
* @param newJwtToken
*/
void
refreshLoginInfo
(
String
oldToken
,
String
username
,
JwtToken
newJwtToken
);
/**
* 通过用户名,从缓存中获取登录用户LoginSysUserRedisVo
*
* @param username
* @return
*/
LoginSysUserRedisVo
getLoginSysUserRedisVo
(
String
username
);
/**
* 获取登录用户对象
*
* @param username
* @return
*/
LoginSysUserVo
getLoginSysUserVo
(
String
username
);
/**
* 通过用户名称获取盐值
*
* @param username
* @return
*/
String
getSalt
(
String
username
);
/**
* 删除对应用户的Redis缓存
*
* @param token
* @param username
*/
void
deleteLoginInfo
(
String
token
,
String
username
);
/**
* 判断token在redis中是否存在
*
* @param token
* @return
*/
boolean
exists
(
String
token
);
/**
* 删除用户所有登录缓存
*
* @param username
*/
void
deleteUserAllCache
(
String
username
);
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/SysLoginRedisService.java
0 → 100755
View file @
543097ed
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
cache
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo
;
/**
* 登录信息Redis缓存操作服务
*
* @author geekidea
* @date 2019-09-30
* @since 1.3.0.RELEASE
**/
public
interface
SysLoginRedisService
{
/**
* 缓存登录信息
*
* @param jwtToken
* @param loginSysUserVo
*/
void
cacheLoginInfo
(
JwtToken
jwtToken
,
LoginSysUserVo
loginSysUserVo
);
/**
* 刷新登录信息
*
* @param oldToken
* @param username
* @param newJwtToken
*/
void
refreshLoginInfo
(
String
oldToken
,
String
username
,
JwtToken
newJwtToken
);
/**
* 通过用户名,从缓存中获取登录用户LoginSysUserRedisVo
*
* @param username
* @return
*/
LoginSysUserRedisVo
getLoginSysUserRedisVo
(
String
username
);
/**
* 获取登录用户对象
*
* @param username
* @return
*/
LoginSysUserVo
getLoginSysUserVo
(
String
username
);
/**
* 通过用户名称获取盐值
*
* @param username
* @return
*/
String
getSalt
(
String
username
);
/**
* 删除对应用户的Redis缓存
*
* @param token
* @param username
*/
void
deleteLoginInfo
(
String
token
,
String
username
);
/**
* 判断token在redis中是否存在
*
* @param token
* @return
*/
boolean
exists
(
String
token
);
/**
* 删除用户所有登录缓存
*
* @param username
*/
void
deleteUserAllCache
(
String
username
);
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/impl/AppLoginRedisServiceImpl.java
0 → 100644
View file @
543097ed
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
cache
.
impl
;
import
io.geekidea.springbootplus.config.constant.AppLoginRedisKey
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.framework.common.bean.ClientInfo
;
import
io.geekidea.springbootplus.framework.shiro.cache.AppLoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.convert.LoginSysUserVoConvert
;
import
io.geekidea.springbootplus.framework.shiro.convert.ShiroMapstructConvert
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.vo.JwtTokenRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo
;
import
io.geekidea.springbootplus.framework.util.ClientInfoUtil
;
import
io.geekidea.springbootplus.framework.util.HttpServletRequestUtil
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
java.time.Duration
;
import
java.util.List
;
import
java.util.Set
;
@Service
public
class
AppLoginRedisServiceImpl
implements
AppLoginRedisService
{
@Autowired
private
JwtProperties
jwtProperties
;
@Autowired
private
RedisTemplate
redisTemplate
;
/**
* key-value: 有过期时间-->token过期时间
* 1. tokenMd5:jwtTokenRedisVo
* 2. username:loginSysUserRedisVo
* 3. username:salt
* hash: 没有过期时间,统计在线的用户信息
* username:num
*/
@Override
public
void
cacheLoginInfo
(
JwtToken
jwtToken
,
LoginSysUserVo
loginSysUserVo
)
{
if
(
jwtToken
==
null
)
{
throw
new
IllegalArgumentException
(
"jwtToken不能为空"
);
}
if
(
loginSysUserVo
==
null
)
{
throw
new
IllegalArgumentException
(
"loginSysUserVo不能为空"
);
}
// token
String
token
=
jwtToken
.
getToken
();
// 盐值
String
salt
=
jwtToken
.
getSalt
();
// 登录用户名称
String
username
=
loginSysUserVo
.
getUsername
();
// token md5值
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
// Redis缓存JWT Token信息
JwtTokenRedisVo
jwtTokenRedisVo
=
ShiroMapstructConvert
.
INSTANCE
.
jwtTokenToJwtTokenRedisVo
(
jwtToken
);
// 用户客户端信息
ClientInfo
clientInfo
=
ClientInfoUtil
.
get
(
HttpServletRequestUtil
.
getRequest
());
// Redis缓存登录用户信息
// 将LoginSysUserVo对象复制到LoginSysUserRedisVo,使用mapstruct进行对象属性复制
LoginSysUserRedisVo
loginSysUserRedisVo
=
LoginSysUserVoConvert
.
INSTANCE
.
voToRedisVo
(
loginSysUserVo
);
loginSysUserRedisVo
.
setSalt
(
salt
);
loginSysUserRedisVo
.
setClientInfo
(
clientInfo
);
// Redis过期时间与JwtToken过期时间一致
Duration
expireDuration
=
Duration
.
ofSeconds
(
jwtToken
.
getExpireSecond
());
// 判断是否启用单个用户登录,如果是,这每个用户只有一个有效token
boolean
singleLogin
=
jwtProperties
.
isSingleLogin
();
if
(
singleLogin
)
{
deleteUserAllCache
(
username
);
}
// 1. tokenMd5:jwtTokenRedisVo
String
loginTokenRedisKey
=
String
.
format
(
AppLoginRedisKey
.
LOGIN_TOKEN
,
tokenMd5
);
redisTemplate
.
opsForValue
().
set
(
loginTokenRedisKey
,
jwtTokenRedisVo
,
expireDuration
);
// 2. username:loginSysUserRedisVo
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_USER
,
username
),
loginSysUserRedisVo
,
expireDuration
);
// 3. salt hash,方便获取盐值鉴权
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_SALT
,
username
),
salt
,
expireDuration
);
// 4. login user token
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_USER_TOKEN
,
username
,
tokenMd5
),
loginTokenRedisKey
,
expireDuration
);
}
@Override
public
void
refreshLoginInfo
(
String
oldToken
,
String
username
,
JwtToken
newJwtToken
)
{
// 获取缓存的登录用户信息
LoginSysUserRedisVo
loginSysUserRedisVo
=
getLoginSysUserRedisVo
(
username
);
// 删除之前的token信息
deleteLoginInfo
(
oldToken
,
username
);
// 缓存登录信息
cacheLoginInfo
(
newJwtToken
,
loginSysUserRedisVo
);
}
@Override
public
LoginSysUserRedisVo
getLoginSysUserRedisVo
(
String
username
)
{
if
(
StringUtils
.
isBlank
(
username
))
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
return
(
LoginSysUserRedisVo
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_USER
,
username
));
}
@Override
public
LoginSysUserVo
getLoginSysUserVo
(
String
username
)
{
if
(
StringUtils
.
isBlank
(
username
))
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
LoginSysUserRedisVo
userRedisVo
=
getLoginSysUserRedisVo
(
username
);
return
userRedisVo
;
}
@Override
public
String
getSalt
(
String
username
)
{
if
(
StringUtils
.
isBlank
(
username
))
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
String
salt
=
(
String
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_SALT
,
username
));
return
salt
;
}
@Override
public
void
deleteLoginInfo
(
String
token
,
String
username
)
{
if
(
token
==
null
)
{
throw
new
IllegalArgumentException
(
"token不能为空"
);
}
if
(
username
==
null
)
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
// 1. delete tokenMd5
redisTemplate
.
delete
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
// 2. delete username
redisTemplate
.
delete
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_USER
,
username
));
// 3. delete salt
redisTemplate
.
delete
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_SALT
,
username
));
// 4. delete user token
redisTemplate
.
delete
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_USER_TOKEN
,
username
,
tokenMd5
));
}
@Override
public
boolean
exists
(
String
token
)
{
if
(
token
==
null
)
{
throw
new
IllegalArgumentException
(
"token不能为空"
);
}
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
Object
object
=
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
return
object
!=
null
;
}
@Override
public
void
deleteUserAllCache
(
String
username
)
{
Set
<
String
>
userTokenMd5Set
=
redisTemplate
.
keys
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_USER_ALL_TOKEN
,
username
));
if
(
CollectionUtils
.
isEmpty
(
userTokenMd5Set
))
{
return
;
}
// 1. 删除登录用户的所有token信息
List
<
String
>
tokenMd5List
=
redisTemplate
.
opsForValue
().
multiGet
(
userTokenMd5Set
);
redisTemplate
.
delete
(
tokenMd5List
);
// 2. 删除登录用户的所有user:token信息
redisTemplate
.
delete
(
userTokenMd5Set
);
// 3. 删除登录用户信息
redisTemplate
.
delete
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_USER
,
username
));
// 4. 删除登录用户盐值信息
redisTemplate
.
delete
(
String
.
format
(
AppLoginRedisKey
.
LOGIN_SALT
,
username
));
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/impl/MerchantLoginRedisServiceImpl.java
0 → 100644
View file @
543097ed
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
cache
.
impl
;
import
io.geekidea.springbootplus.config.constant.MerchantLoginRedisKey
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.framework.common.bean.ClientInfo
;
import
io.geekidea.springbootplus.framework.shiro.cache.MerchantLoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.convert.LoginSysUserVoConvert
;
import
io.geekidea.springbootplus.framework.shiro.convert.ShiroMapstructConvert
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.vo.JwtTokenRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserVo
;
import
io.geekidea.springbootplus.framework.util.ClientInfoUtil
;
import
io.geekidea.springbootplus.framework.util.HttpServletRequestUtil
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
java.time.Duration
;
import
java.util.List
;
import
java.util.Set
;
@Service
public
class
MerchantLoginRedisServiceImpl
implements
MerchantLoginRedisService
{
@Autowired
private
JwtProperties
jwtProperties
;
@Autowired
private
RedisTemplate
redisTemplate
;
/**
* key-value: 有过期时间-->token过期时间
* 1. tokenMd5:jwtTokenRedisVo
* 2. username:loginSysUserRedisVo
* 3. username:salt
* hash: 没有过期时间,统计在线的用户信息
* username:num
*/
@Override
public
void
cacheLoginInfo
(
JwtToken
jwtToken
,
LoginSysUserVo
loginSysUserVo
)
{
if
(
jwtToken
==
null
)
{
throw
new
IllegalArgumentException
(
"jwtToken不能为空"
);
}
if
(
loginSysUserVo
==
null
)
{
throw
new
IllegalArgumentException
(
"loginSysUserVo不能为空"
);
}
// token
String
token
=
jwtToken
.
getToken
();
// 盐值
String
salt
=
jwtToken
.
getSalt
();
// 登录用户名称
String
username
=
loginSysUserVo
.
getUsername
();
// token md5值
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
// Redis缓存JWT Token信息
JwtTokenRedisVo
jwtTokenRedisVo
=
ShiroMapstructConvert
.
INSTANCE
.
jwtTokenToJwtTokenRedisVo
(
jwtToken
);
// 用户客户端信息
ClientInfo
clientInfo
=
ClientInfoUtil
.
get
(
HttpServletRequestUtil
.
getRequest
());
// Redis缓存登录用户信息
// 将LoginSysUserVo对象复制到LoginSysUserRedisVo,使用mapstruct进行对象属性复制
LoginSysUserRedisVo
loginSysUserRedisVo
=
LoginSysUserVoConvert
.
INSTANCE
.
voToRedisVo
(
loginSysUserVo
);
loginSysUserRedisVo
.
setSalt
(
salt
);
loginSysUserRedisVo
.
setClientInfo
(
clientInfo
);
// Redis过期时间与JwtToken过期时间一致
Duration
expireDuration
=
Duration
.
ofSeconds
(
jwtToken
.
getExpireSecond
());
// 判断是否启用单个用户登录,如果是,这每个用户只有一个有效token
boolean
singleLogin
=
jwtProperties
.
isSingleLogin
();
if
(
singleLogin
)
{
deleteUserAllCache
(
username
);
}
// 1. tokenMd5:jwtTokenRedisVo
String
loginTokenRedisKey
=
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_TOKEN
,
tokenMd5
);
redisTemplate
.
opsForValue
().
set
(
loginTokenRedisKey
,
jwtTokenRedisVo
,
expireDuration
);
// 2. username:loginSysUserRedisVo
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_USER
,
username
),
loginSysUserRedisVo
,
expireDuration
);
// 3. salt hash,方便获取盐值鉴权
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_SALT
,
username
),
salt
,
expireDuration
);
// 4. login user token
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_USER_TOKEN
,
username
,
tokenMd5
),
loginTokenRedisKey
,
expireDuration
);
}
@Override
public
void
refreshLoginInfo
(
String
oldToken
,
String
username
,
JwtToken
newJwtToken
)
{
// 获取缓存的登录用户信息
LoginSysUserRedisVo
loginSysUserRedisVo
=
getLoginSysUserRedisVo
(
username
);
// 删除之前的token信息
deleteLoginInfo
(
oldToken
,
username
);
// 缓存登录信息
cacheLoginInfo
(
newJwtToken
,
loginSysUserRedisVo
);
}
@Override
public
LoginSysUserRedisVo
getLoginSysUserRedisVo
(
String
username
)
{
if
(
StringUtils
.
isBlank
(
username
))
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
return
(
LoginSysUserRedisVo
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_USER
,
username
));
}
@Override
public
LoginSysUserVo
getLoginSysUserVo
(
String
username
)
{
if
(
StringUtils
.
isBlank
(
username
))
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
LoginSysUserRedisVo
userRedisVo
=
getLoginSysUserRedisVo
(
username
);
return
userRedisVo
;
}
@Override
public
String
getSalt
(
String
username
)
{
if
(
StringUtils
.
isBlank
(
username
))
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
String
salt
=
(
String
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_SALT
,
username
));
return
salt
;
}
@Override
public
void
deleteLoginInfo
(
String
token
,
String
username
)
{
if
(
token
==
null
)
{
throw
new
IllegalArgumentException
(
"token不能为空"
);
}
if
(
username
==
null
)
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
// 1. delete tokenMd5
redisTemplate
.
delete
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
// 2. delete username
redisTemplate
.
delete
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_USER
,
username
));
// 3. delete salt
redisTemplate
.
delete
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_SALT
,
username
));
// 4. delete user token
redisTemplate
.
delete
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_USER_TOKEN
,
username
,
tokenMd5
));
}
@Override
public
boolean
exists
(
String
token
)
{
if
(
token
==
null
)
{
throw
new
IllegalArgumentException
(
"token不能为空"
);
}
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
Object
object
=
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
return
object
!=
null
;
}
@Override
public
void
deleteUserAllCache
(
String
username
)
{
Set
<
String
>
userTokenMd5Set
=
redisTemplate
.
keys
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_USER_ALL_TOKEN
,
username
));
if
(
CollectionUtils
.
isEmpty
(
userTokenMd5Set
))
{
return
;
}
// 1. 删除登录用户的所有token信息
List
<
String
>
tokenMd5List
=
redisTemplate
.
opsForValue
().
multiGet
(
userTokenMd5Set
);
redisTemplate
.
delete
(
tokenMd5List
);
// 2. 删除登录用户的所有user:token信息
redisTemplate
.
delete
(
userTokenMd5Set
);
// 3. 删除登录用户信息
redisTemplate
.
delete
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_USER
,
username
));
// 4. 删除登录用户盐值信息
redisTemplate
.
delete
(
String
.
format
(
MerchantLoginRedisKey
.
LOGIN_SALT
,
username
));
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/impl/LoginRedisServiceImpl.java
→
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/cache/impl/
Sys
LoginRedisServiceImpl.java
View file @
543097ed
...
@@ -16,10 +16,10 @@
...
@@ -16,10 +16,10 @@
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
cache
.
impl
;
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
cache
.
impl
;
import
io.geekidea.springbootplus.config.constant.
Commo
nRedisKey
;
import
io.geekidea.springbootplus.config.constant.
SysLogi
nRedisKey
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.framework.common.bean.ClientInfo
;
import
io.geekidea.springbootplus.framework.common.bean.ClientInfo
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.
Sys
LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.convert.LoginSysUserVoConvert
;
import
io.geekidea.springbootplus.framework.shiro.convert.LoginSysUserVoConvert
;
import
io.geekidea.springbootplus.framework.shiro.convert.ShiroMapstructConvert
;
import
io.geekidea.springbootplus.framework.shiro.convert.ShiroMapstructConvert
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
...
@@ -47,7 +47,7 @@ import java.util.Set;
...
@@ -47,7 +47,7 @@ import java.util.Set;
* @since 1.3.0.RELEASE
* @since 1.3.0.RELEASE
**/
**/
@Service
@Service
public
class
LoginRedisServiceImpl
implements
LoginRedisService
{
public
class
SysLoginRedisServiceImpl
implements
Sys
LoginRedisService
{
@Autowired
@Autowired
private
JwtProperties
jwtProperties
;
private
JwtProperties
jwtProperties
;
...
@@ -102,14 +102,14 @@ public class LoginRedisServiceImpl implements LoginRedisService {
...
@@ -102,14 +102,14 @@ public class LoginRedisServiceImpl implements LoginRedisService {
}
}
// 1. tokenMd5:jwtTokenRedisVo
// 1. tokenMd5:jwtTokenRedisVo
String
loginTokenRedisKey
=
String
.
format
(
Commo
nRedisKey
.
LOGIN_TOKEN
,
tokenMd5
);
String
loginTokenRedisKey
=
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_TOKEN
,
tokenMd5
);
redisTemplate
.
opsForValue
().
set
(
loginTokenRedisKey
,
jwtTokenRedisVo
,
expireDuration
);
redisTemplate
.
opsForValue
().
set
(
loginTokenRedisKey
,
jwtTokenRedisVo
,
expireDuration
);
// 2. username:loginSysUserRedisVo
// 2. username:loginSysUserRedisVo
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_USER
,
username
),
loginSysUserRedisVo
,
expireDuration
);
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_USER
,
username
),
loginSysUserRedisVo
,
expireDuration
);
// 3. salt hash,方便获取盐值鉴权
// 3. salt hash,方便获取盐值鉴权
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_SALT
,
username
),
salt
,
expireDuration
);
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_SALT
,
username
),
salt
,
expireDuration
);
// 4. login user token
// 4. login user token
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_USER_TOKEN
,
username
,
tokenMd5
),
loginTokenRedisKey
,
expireDuration
);
redisTemplate
.
opsForValue
().
set
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_USER_TOKEN
,
username
,
tokenMd5
),
loginTokenRedisKey
,
expireDuration
);
}
}
@Override
@Override
...
@@ -127,7 +127,7 @@ public class LoginRedisServiceImpl implements LoginRedisService {
...
@@ -127,7 +127,7 @@ public class LoginRedisServiceImpl implements LoginRedisService {
if
(
StringUtils
.
isBlank
(
username
))
{
if
(
StringUtils
.
isBlank
(
username
))
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
}
return
(
LoginSysUserRedisVo
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_USER
,
username
));
return
(
LoginSysUserRedisVo
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_USER
,
username
));
}
}
@Override
@Override
...
@@ -144,7 +144,7 @@ public class LoginRedisServiceImpl implements LoginRedisService {
...
@@ -144,7 +144,7 @@ public class LoginRedisServiceImpl implements LoginRedisService {
if
(
StringUtils
.
isBlank
(
username
))
{
if
(
StringUtils
.
isBlank
(
username
))
{
throw
new
IllegalArgumentException
(
"username不能为空"
);
throw
new
IllegalArgumentException
(
"username不能为空"
);
}
}
String
salt
=
(
String
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_SALT
,
username
));
String
salt
=
(
String
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_SALT
,
username
));
return
salt
;
return
salt
;
}
}
...
@@ -158,13 +158,13 @@ public class LoginRedisServiceImpl implements LoginRedisService {
...
@@ -158,13 +158,13 @@ public class LoginRedisServiceImpl implements LoginRedisService {
}
}
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
// 1. delete tokenMd5
// 1. delete tokenMd5
redisTemplate
.
delete
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
redisTemplate
.
delete
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
// 2. delete username
// 2. delete username
redisTemplate
.
delete
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_USER
,
username
));
redisTemplate
.
delete
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_USER
,
username
));
// 3. delete salt
// 3. delete salt
redisTemplate
.
delete
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_SALT
,
username
));
redisTemplate
.
delete
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_SALT
,
username
));
// 4. delete user token
// 4. delete user token
redisTemplate
.
delete
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_USER_TOKEN
,
username
,
tokenMd5
));
redisTemplate
.
delete
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_USER_TOKEN
,
username
,
tokenMd5
));
}
}
@Override
@Override
...
@@ -173,13 +173,13 @@ public class LoginRedisServiceImpl implements LoginRedisService {
...
@@ -173,13 +173,13 @@ public class LoginRedisServiceImpl implements LoginRedisService {
throw
new
IllegalArgumentException
(
"token不能为空"
);
throw
new
IllegalArgumentException
(
"token不能为空"
);
}
}
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
Object
object
=
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
Object
object
=
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
return
object
!=
null
;
return
object
!=
null
;
}
}
@Override
@Override
public
void
deleteUserAllCache
(
String
username
)
{
public
void
deleteUserAllCache
(
String
username
)
{
Set
<
String
>
userTokenMd5Set
=
redisTemplate
.
keys
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_USER_ALL_TOKEN
,
username
));
Set
<
String
>
userTokenMd5Set
=
redisTemplate
.
keys
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_USER_ALL_TOKEN
,
username
));
if
(
CollectionUtils
.
isEmpty
(
userTokenMd5Set
))
{
if
(
CollectionUtils
.
isEmpty
(
userTokenMd5Set
))
{
return
;
return
;
}
}
...
@@ -190,9 +190,9 @@ public class LoginRedisServiceImpl implements LoginRedisService {
...
@@ -190,9 +190,9 @@ public class LoginRedisServiceImpl implements LoginRedisService {
// 2. 删除登录用户的所有user:token信息
// 2. 删除登录用户的所有user:token信息
redisTemplate
.
delete
(
userTokenMd5Set
);
redisTemplate
.
delete
(
userTokenMd5Set
);
// 3. 删除登录用户信息
// 3. 删除登录用户信息
redisTemplate
.
delete
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_USER
,
username
));
redisTemplate
.
delete
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_USER
,
username
));
// 4. 删除登录用户盐值信息
// 4. 删除登录用户盐值信息
redisTemplate
.
delete
(
String
.
format
(
Commo
nRedisKey
.
LOGIN_SALT
,
username
));
redisTemplate
.
delete
(
String
.
format
(
SysLogi
nRedisKey
.
LOGIN_SALT
,
username
));
}
}
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/JwtFilter.java
View file @
543097ed
...
@@ -16,21 +16,25 @@
...
@@ -16,21 +16,25 @@
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
;
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
;
import
io.geekidea.springbootplus.config.constant.SysLoginRedisKey
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.framework.common.api.ApiCode
;
import
io.geekidea.springbootplus.framework.common.api.ApiCode
;
import
io.geekidea.springbootplus.framework.common.api.ApiResult
;
import
io.geekidea.springbootplus.framework.common.api.ApiResult
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.
Sys
LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService
;
import
io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtUtil
;
import
io.geekidea.springbootplus.framework.shiro.vo.JwtTokenRedisVo
;
import
io.geekidea.springbootplus.framework.util.HttpServletResponseUtil
;
import
io.geekidea.springbootplus.framework.util.HttpServletResponseUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.authc.AuthenticationToken
;
import
org.apache.shiro.authc.AuthenticationToken
;
import
org.apache.shiro.subject.Subject
;
import
org.apache.shiro.subject.Subject
;
import
org.apache.shiro.web.filter.authc.AuthenticatingFilter
;
import
org.apache.shiro.web.filter.authc.AuthenticatingFilter
;
import
org.apache.shiro.web.util.WebUtils
;
import
org.apache.shiro.web.util.WebUtils
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.ServletResponse
;
...
@@ -47,16 +51,19 @@ import javax.servlet.http.HttpServletResponse;
...
@@ -47,16 +51,19 @@ import javax.servlet.http.HttpServletResponse;
@Slf4j
@Slf4j
public
class
JwtFilter
extends
AuthenticatingFilter
{
public
class
JwtFilter
extends
AuthenticatingFilter
{
private
RedisTemplate
redisTemplate
;
private
final
ShiroLoginService
shiroLoginService
;
private
final
ShiroLoginService
shiroLoginService
;
private
final
LoginRedisService
l
oginRedisService
;
private
final
SysLoginRedisService
sysL
oginRedisService
;
private
final
JwtProperties
jwtProperties
;
private
final
JwtProperties
jwtProperties
;
public
JwtFilter
(
ShiroLoginService
shiroLoginService
,
LoginRedisService
loginRedisService
,
JwtProperties
jwtProperties
)
{
public
JwtFilter
(
ShiroLoginService
shiroLoginService
,
SysLoginRedisService
loginRedisService
,
JwtProperties
jwtProperties
,
RedisTemplate
redisTemplate
)
{
this
.
shiroLoginService
=
shiroLoginService
;
this
.
shiroLoginService
=
shiroLoginService
;
this
.
l
oginRedisService
=
loginRedisService
;
this
.
sysL
oginRedisService
=
loginRedisService
;
this
.
jwtProperties
=
jwtProperties
;
this
.
jwtProperties
=
jwtProperties
;
this
.
redisTemplate
=
redisTemplate
;
}
}
/**
/**
...
@@ -77,22 +84,29 @@ public class JwtFilter extends AuthenticatingFilter {
...
@@ -77,22 +84,29 @@ public class JwtFilter extends AuthenticatingFilter {
throw
new
AuthenticationException
(
"JWT Token已过期,token:"
+
token
);
throw
new
AuthenticationException
(
"JWT Token已过期,token:"
+
token
);
}
}
Object
jwtTokenRedisVo
=
null
;
// 如果开启redis二次校验,或者设置为单个用户token登录,则先在redis中判断token是否存在
// 如果开启redis二次校验,或者设置为单个用户token登录,则先在redis中判断token是否存在
if
(
jwtProperties
.
isRedisCheck
()
||
jwtProperties
.
isSingleLogin
())
{
if
(
jwtProperties
.
isRedisCheck
()
||
jwtProperties
.
isSingleLogin
())
{
boolean
redisExpired
=
loginRedisService
.
exists
(
token
);
String
tokenMd5
=
DigestUtils
.
md5Hex
(
token
);
if
(!
redisExpired
)
{
jwtTokenRedisVo
=
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
SysLoginRedisKey
.
LOGIN_TOKEN
,
tokenMd5
));
// boolean redisExpired = sysLoginRedisService.exists(token);
if
(
jwtTokenRedisVo
==
null
)
{
throw
new
AuthenticationException
(
"Redis Token不存在,token:"
+
token
);
throw
new
AuthenticationException
(
"Redis Token不存在,token:"
+
token
);
}
}
}
}
String
username
=
JwtUtil
.
getUsername
(
token
);
String
username
=
JwtUtil
.
getUsername
(
token
);
String
salt
;
String
salt
;
if
(
jwtProperties
.
isSaltCheck
())
{
if
(
jwtProperties
.
isSaltCheck
())
{
salt
=
l
oginRedisService
.
getSalt
(
username
);
salt
=
sysL
oginRedisService
.
getSalt
(
username
);
}
else
{
}
else
{
salt
=
jwtProperties
.
getSecret
();
salt
=
jwtProperties
.
getSecret
();
}
}
return
JwtToken
.
build
(
token
,
username
,
salt
,
jwtProperties
.
getExpireSecond
());
JwtTokenRedisVo
jwt
=
(
JwtTokenRedisVo
)
jwtTokenRedisVo
;
return
JwtToken
.
build
(
token
,
username
,
salt
,
jwtProperties
.
getExpireSecond
(),
jwt
.
getType
());
}
}
/**
/**
...
@@ -118,6 +132,7 @@ public class JwtFilter extends AuthenticatingFilter {
...
@@ -118,6 +132,7 @@ public class JwtFilter extends AuthenticatingFilter {
}
}
/**
/**
* 执行登陆认证
* 判断是否允许访问
* 判断是否允许访问
*
*
* @param request
* @param request
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/JwtRealmSystem.java
deleted
100755 → 0
View file @
19573744
/*
* Copyright 2019-2029 geekidea(https://github.com/geekidea)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.SetUtils
;
import
org.apache.commons.lang3.StringUtils
;
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
;
/**
* Shiro 授权认证-系统
*
* @author geekidea
* @date 2019-09-27
* @since 1.3.0.RELEASE
**/
@Slf4j
public
class
JwtRealmSystem
extends
AuthorizingRealm
{
private
LoginRedisService
loginRedisService
;
public
JwtRealmSystem
(
LoginRedisService
loginRedisService
)
{
this
.
loginRedisService
=
loginRedisService
;
}
@Override
public
boolean
supports
(
AuthenticationToken
token
)
{
return
token
!=
null
&&
token
instanceof
JwtToken
;
}
/**
* 授权认证,设置角色/权限信息
*
* @param principalCollection
* @return
*/
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
log
.
debug
(
"doGetAuthorizationInfo principalCollection..."
);
// 设置角色/权限信息
JwtToken
jwtToken
=
(
JwtToken
)
principalCollection
.
getPrimaryPrincipal
();
// 获取username
String
username
=
jwtToken
.
getUsername
();
// 获取登录用户角色权限信息
LoginSysUserRedisVo
loginSysUserRedisVo
=
loginRedisService
.
getLoginSysUserRedisVo
(
username
);
SimpleAuthorizationInfo
authorizationInfo
=
new
SimpleAuthorizationInfo
();
// 设置角色
authorizationInfo
.
setRoles
(
SetUtils
.
hashSet
(
loginSysUserRedisVo
.
getRoleCode
()));
// 设置权限
authorizationInfo
.
setStringPermissions
(
loginSysUserRedisVo
.
getPermissionCodes
());
return
authorizationInfo
;
}
/**
* 登录认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected
AuthenticationInfo
doGetAuthenticationInfo
(
AuthenticationToken
authenticationToken
)
throws
AuthenticationException
{
log
.
debug
(
"doGetAuthenticationInfo authenticationToken..."
);
// 校验token
JwtToken
jwtToken
=
(
JwtToken
)
authenticationToken
;
if
(
jwtToken
==
null
)
{
throw
new
AuthenticationException
(
"jwtToken不能为空"
);
}
String
salt
=
jwtToken
.
getSalt
();
if
(
StringUtils
.
isBlank
(
salt
))
{
throw
new
AuthenticationException
(
"salt不能为空"
);
}
return
new
SimpleAuthenticationInfo
(
jwtToken
,
salt
,
getName
()
);
}
}
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/JwtToken.java
View file @
543097ed
...
@@ -37,6 +37,8 @@ import java.util.Date;
...
@@ -37,6 +37,8 @@ import java.util.Date;
public
class
JwtToken
implements
HostAuthenticationToken
{
public
class
JwtToken
implements
HostAuthenticationToken
{
private
static
final
long
serialVersionUID
=
5101247566043093405L
;
private
static
final
long
serialVersionUID
=
5101247566043093405L
;
private
String
type
;
/**
/**
* 登录ip
* 登录ip
*/
*/
...
@@ -70,7 +72,7 @@ public class JwtToken implements HostAuthenticationToken {
...
@@ -70,7 +72,7 @@ public class JwtToken implements HostAuthenticationToken {
private
String
credentials
;
private
String
credentials
;
public
static
JwtToken
build
(
String
token
,
String
username
,
String
salt
,
long
expireSecond
)
{
public
static
JwtToken
build
(
String
token
,
String
username
,
String
salt
,
long
expireSecond
,
String
type
)
{
DecodedJWT
decodedJwt
=
JwtUtil
.
getJwtInfo
(
token
);
DecodedJWT
decodedJwt
=
JwtUtil
.
getJwtInfo
(
token
);
Date
createDate
=
decodedJwt
.
getIssuedAt
();
Date
createDate
=
decodedJwt
.
getIssuedAt
();
Date
expireDate
=
decodedJwt
.
getExpiresAt
();
Date
expireDate
=
decodedJwt
.
getExpiresAt
();
...
@@ -79,6 +81,7 @@ public class JwtToken implements HostAuthenticationToken {
...
@@ -79,6 +81,7 @@ public class JwtToken implements HostAuthenticationToken {
.
setToken
(
token
)
.
setToken
(
token
)
.
setHost
(
IpUtil
.
getRequestIp
())
.
setHost
(
IpUtil
.
getRequestIp
())
.
setSalt
(
salt
)
.
setSalt
(
salt
)
.
setType
(
type
)
.
setCreateDate
(
createDate
)
.
setCreateDate
(
createDate
)
.
setExpireSecond
(
expireSecond
)
.
setExpireSecond
(
expireSecond
)
.
setExpireDate
(
expireDate
);
.
setExpireDate
(
expireDate
);
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/realm/JwtRealmAppUser.java
View file @
543097ed
...
@@ -16,9 +16,8 @@
...
@@ -16,9 +16,8 @@
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
.
realm
;
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
.
realm
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.
App
LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.SetUtils
;
import
org.apache.commons.collections4.SetUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
...
@@ -41,10 +40,10 @@ import org.apache.shiro.subject.PrincipalCollection;
...
@@ -41,10 +40,10 @@ import org.apache.shiro.subject.PrincipalCollection;
@Slf4j
@Slf4j
public
class
JwtRealmAppUser
extends
AuthorizingRealm
{
public
class
JwtRealmAppUser
extends
AuthorizingRealm
{
private
LoginRedisService
l
oginRedisService
;
private
AppLoginRedisService
appL
oginRedisService
;
public
JwtRealmAppUser
(
LoginRedisService
l
oginRedisService
)
{
public
JwtRealmAppUser
(
AppLoginRedisService
appL
oginRedisService
)
{
this
.
loginRedisService
=
l
oginRedisService
;
this
.
appLoginRedisService
=
appL
oginRedisService
;
}
}
@Override
@Override
...
@@ -63,15 +62,24 @@ public class JwtRealmAppUser extends AuthorizingRealm {
...
@@ -63,15 +62,24 @@ public class JwtRealmAppUser extends AuthorizingRealm {
log
.
debug
(
"doGetAuthorizationInfo principalCollection..."
);
log
.
debug
(
"doGetAuthorizationInfo principalCollection..."
);
// 设置角色/权限信息
// 设置角色/权限信息
JwtToken
jwtToken
=
(
JwtToken
)
principalCollection
.
getPrimaryPrincipal
();
JwtToken
jwtToken
=
(
JwtToken
)
principalCollection
.
getPrimaryPrincipal
();
if
(!
jwtToken
.
getType
().
equals
(
"app"
))
{
return
null
;
}
/*
// 获取username
// 获取username
String username = jwtToken.getUsername();
String username = jwtToken.getUsername();
// 获取登录用户角色权限信息
// 获取登录用户角色权限信息
LoginSysUserRedisVo
loginSysUserRedisVo
=
l
oginRedisService
.
getLoginSysUserRedisVo
(
username
);
LoginSysUserRedisVo loginSysUserRedisVo =
appL
oginRedisService.getLoginSysUserRedisVo(username);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 设置角色
// 设置角色
authorizationInfo.setRoles(SetUtils.hashSet(loginSysUserRedisVo.getRoleCode()));
authorizationInfo.setRoles(SetUtils.hashSet(loginSysUserRedisVo.getRoleCode()));
// 设置权限
// 设置权限
authorizationInfo
.
setStringPermissions
(
loginSysUserRedisVo
.
getPermissionCodes
());
authorizationInfo.setStringPermissions(loginSysUserRedisVo.getPermissionCodes());*/
SimpleAuthorizationInfo
authorizationInfo
=
new
SimpleAuthorizationInfo
();
// 设置角色
authorizationInfo
.
setRoles
(
SetUtils
.
hashSet
(
"app:all"
));
return
authorizationInfo
;
return
authorizationInfo
;
}
}
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/JwtRealmMerchant.java
→
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/
realm/
JwtRealmMerchant.java
View file @
543097ed
...
@@ -14,9 +14,10 @@
...
@@ -14,9 +14,10 @@
* limitations under the License.
* limitations under the License.
*/
*/
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
;
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
.
realm
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.MerchantLoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.SetUtils
;
import
org.apache.commons.collections4.SetUtils
;
...
@@ -40,10 +41,10 @@ import org.apache.shiro.subject.PrincipalCollection;
...
@@ -40,10 +41,10 @@ import org.apache.shiro.subject.PrincipalCollection;
@Slf4j
@Slf4j
public
class
JwtRealmMerchant
extends
AuthorizingRealm
{
public
class
JwtRealmMerchant
extends
AuthorizingRealm
{
private
LoginRedisService
l
oginRedisService
;
private
MerchantLoginRedisService
merchantL
oginRedisService
;
public
JwtRealmMerchant
(
LoginRedisService
l
oginRedisService
)
{
public
JwtRealmMerchant
(
MerchantLoginRedisService
merchantL
oginRedisService
)
{
this
.
loginRedisService
=
l
oginRedisService
;
this
.
merchantLoginRedisService
=
merchantL
oginRedisService
;
}
}
@Override
@Override
...
@@ -59,19 +60,27 @@ public class JwtRealmMerchant extends AuthorizingRealm {
...
@@ -59,19 +60,27 @@ public class JwtRealmMerchant extends AuthorizingRealm {
*/
*/
@Override
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
log
.
debug
(
"doGetAuthorizationInfo principalCollection..."
);
log
.
debug
(
"doGetAuthorizationInfo principalCollection..."
);
// 设置角色/权限信息
// 设置角色/权限信息
JwtToken
jwtToken
=
(
JwtToken
)
principalCollection
.
getPrimaryPrincipal
();
JwtToken
jwtToken
=
(
JwtToken
)
principalCollection
.
getPrimaryPrincipal
();
if
(!
jwtToken
.
getType
().
equals
(
"mer"
))
{
return
null
;
}
// 获取username
// 获取username
String
username
=
jwtToken
.
getUsername
();
String
username
=
jwtToken
.
getUsername
();
// 获取登录用户角色权限信息
// 获取登录用户角色权限信息
LoginSysUserRedisVo
loginSysUserRedisVo
=
l
oginRedisService
.
getLoginSysUserRedisVo
(
username
);
LoginSysUserRedisVo
loginSysUserRedisVo
=
merchantL
oginRedisService
.
getLoginSysUserRedisVo
(
username
);
SimpleAuthorizationInfo
authorizationInfo
=
new
SimpleAuthorizationInfo
();
SimpleAuthorizationInfo
authorizationInfo
=
new
SimpleAuthorizationInfo
();
// 设置角色
// 设置角色
authorizationInfo
.
setRoles
(
SetUtils
.
hashSet
(
loginSysUserRedisVo
.
getRoleCode
()));
authorizationInfo
.
setRoles
(
SetUtils
.
hashSet
(
loginSysUserRedisVo
.
getRoleCode
()));
// 设置权限
// 设置权限
authorizationInfo
.
setStringPermissions
(
loginSysUserRedisVo
.
getPermissionCodes
());
authorizationInfo
.
setStringPermissions
(
loginSysUserRedisVo
.
getPermissionCodes
());
return
authorizationInfo
;
return
authorizationInfo
;
}
}
/**
/**
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/
JwtReal
m.java
→
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/jwt/
realm/JwtRealmSyste
m.java
View file @
543097ed
...
@@ -14,9 +14,10 @@
...
@@ -14,9 +14,10 @@
* limitations under the License.
* limitations under the License.
*/
*/
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
;
package
io
.
geekidea
.
springbootplus
.
framework
.
shiro
.
jwt
.
realm
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.SysLoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.SetUtils
;
import
org.apache.commons.collections4.SetUtils
;
...
@@ -38,12 +39,12 @@ import org.apache.shiro.subject.PrincipalCollection;
...
@@ -38,12 +39,12 @@ import org.apache.shiro.subject.PrincipalCollection;
* @since 1.3.0.RELEASE
* @since 1.3.0.RELEASE
**/
**/
@Slf4j
@Slf4j
public
class
JwtRealm
extends
AuthorizingRealm
{
public
class
JwtRealm
System
extends
AuthorizingRealm
{
private
LoginRedisService
l
oginRedisService
;
private
SysLoginRedisService
sysL
oginRedisService
;
public
JwtRealm
(
LoginRedisService
l
oginRedisService
)
{
public
JwtRealm
System
(
SysLoginRedisService
sysL
oginRedisService
)
{
this
.
loginRedisService
=
l
oginRedisService
;
this
.
sysLoginRedisService
=
sysL
oginRedisService
;
}
}
@Override
@Override
...
@@ -52,21 +53,25 @@ public class JwtRealm extends AuthorizingRealm {
...
@@ -52,21 +53,25 @@ public class JwtRealm extends AuthorizingRealm {
}
}
/**
/**
*
授权认证,设置角色/权限信息
*
获取用户权限信息,包括角色以及权限。只有当触发检测用户权限时才会调用此方法,例如checkRole,checkPermission
*
*
* @param principalCollection
* @return AuthorizationInfo 权限信息
* @return
*/
*/
@Override
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
log
.
debug
(
"doGetAuthorizationInfo principalCollection..."
);
log
.
debug
(
"doGetAuthorizationInfo principalCollection..."
);
// 设置角色/权限信息
// 设置角色/权限信息
JwtToken
jwtToken
=
(
JwtToken
)
principalCollection
.
getPrimaryPrincipal
();
JwtToken
jwtToken
=
(
JwtToken
)
principalCollection
.
getPrimaryPrincipal
();
if
(!
jwtToken
.
getType
().
equals
(
"sys"
)){
return
null
;
}
// 获取username
// 获取username
String
username
=
jwtToken
.
getUsername
();
String
username
=
jwtToken
.
getUsername
();
// 获取登录用户角色权限信息
// 获取登录用户角色权限信息
LoginSysUserRedisVo
loginSysUserRedisVo
=
l
oginRedisService
.
getLoginSysUserRedisVo
(
username
);
LoginSysUserRedisVo
loginSysUserRedisVo
=
sysL
oginRedisService
.
getLoginSysUserRedisVo
(
username
);
SimpleAuthorizationInfo
authorizationInfo
=
new
SimpleAuthorizationInfo
();
SimpleAuthorizationInfo
authorizationInfo
=
new
SimpleAuthorizationInfo
();
// 设置角色
// 设置角色
authorizationInfo
.
setRoles
(
SetUtils
.
hashSet
(
loginSysUserRedisVo
.
getRoleCode
()));
authorizationInfo
.
setRoles
(
SetUtils
.
hashSet
(
loginSysUserRedisVo
.
getRoleCode
()));
// 设置权限
// 设置权限
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/service/impl/ShiroLoginServiceImpl.java
View file @
543097ed
...
@@ -19,7 +19,7 @@ package io.geekidea.springbootplus.framework.shiro.service.impl;
...
@@ -19,7 +19,7 @@ package io.geekidea.springbootplus.framework.shiro.service.impl;
import
io.geekidea.springbootplus.config.constant.CommonConstant
;
import
io.geekidea.springbootplus.config.constant.CommonConstant
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.JwtProperties
;
import
io.geekidea.springbootplus.config.properties.SpringBootPlusProperties
;
import
io.geekidea.springbootplus.config.properties.SpringBootPlusProperties
;
import
io.geekidea.springbootplus.framework.shiro.cache.LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.cache.
Sys
LoginRedisService
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.jwt.JwtToken
;
import
io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService
;
import
io.geekidea.springbootplus.framework.shiro.service.ShiroLoginService
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil
;
...
@@ -50,7 +50,7 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
...
@@ -50,7 +50,7 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
@Lazy
@Lazy
@Autowired
@Autowired
private
LoginRedisService
l
oginRedisService
;
private
SysLoginRedisService
sysL
oginRedisService
;
@Lazy
@Lazy
@Autowired
@Autowired
...
@@ -92,7 +92,7 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
...
@@ -92,7 +92,7 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
// 如果token继续发往后台,则提示,此token已失效,请使用新token,不在返回新token,返回状态码:461
// 如果token继续发往后台,则提示,此token已失效,请使用新token,不在返回新token,返回状态码:461
// 如果Redis缓存中没有,JwtToken没有过期,则说明,已经刷新token
// 如果Redis缓存中没有,JwtToken没有过期,则说明,已经刷新token
boolean
exists
=
l
oginRedisService
.
exists
(
token
);
boolean
exists
=
sysL
oginRedisService
.
exists
(
token
);
if
(!
exists
)
{
if
(!
exists
)
{
httpServletResponse
.
setStatus
(
CommonConstant
.
JWT_INVALID_TOKEN_CODE
);
httpServletResponse
.
setStatus
(
CommonConstant
.
JWT_INVALID_TOKEN_CODE
);
throw
new
AuthenticationException
(
"token已无效,请使用已刷新的token"
);
throw
new
AuthenticationException
(
"token已无效,请使用已刷新的token"
);
...
@@ -103,9 +103,9 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
...
@@ -103,9 +103,9 @@ public class ShiroLoginServiceImpl implements ShiroLoginService {
// 生成新token字符串
// 生成新token字符串
String
newToken
=
JwtUtil
.
generateToken
(
username
,
salt
,
Duration
.
ofSeconds
(
expireSecond
));
String
newToken
=
JwtUtil
.
generateToken
(
username
,
salt
,
Duration
.
ofSeconds
(
expireSecond
));
// 生成新JwtToken对象
// 生成新JwtToken对象
JwtToken
newJwtToken
=
JwtToken
.
build
(
newToken
,
username
,
salt
,
expireSecond
);
JwtToken
newJwtToken
=
JwtToken
.
build
(
newToken
,
username
,
salt
,
expireSecond
,
jwtToken
.
getType
()
);
// 更新redis缓存
// 更新redis缓存
l
oginRedisService
.
refreshLoginInfo
(
token
,
username
,
newJwtToken
);
sysL
oginRedisService
.
refreshLoginInfo
(
token
,
username
,
newJwtToken
);
log
.
debug
(
"刷新token成功,原token:{},新token:{}"
,
token
,
newToken
);
log
.
debug
(
"刷新token成功,原token:{},新token:{}"
,
token
,
newToken
);
// 设置响应头
// 设置响应头
// 刷新token
// 刷新token
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/util/JwtUtil.java
View file @
543097ed
...
@@ -110,6 +110,13 @@ public class JwtUtil {
...
@@ -110,6 +110,13 @@ public class JwtUtil {
return
null
;
return
null
;
}
}
/**
* 验证token
*
* @param token
* @param salt
* @return
*/
public
static
boolean
verifyToken
(
String
token
,
String
salt
)
{
public
static
boolean
verifyToken
(
String
token
,
String
salt
)
{
try
{
try
{
Algorithm
algorithm
=
Algorithm
.
HMAC256
(
salt
);
Algorithm
algorithm
=
Algorithm
.
HMAC256
(
salt
);
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/shiro/vo/JwtTokenRedisVo.java
View file @
543097ed
...
@@ -32,6 +32,9 @@ import java.util.Date;
...
@@ -32,6 +32,9 @@ import java.util.Date;
@Accessors
(
chain
=
true
)
@Accessors
(
chain
=
true
)
public
class
JwtTokenRedisVo
implements
Serializable
{
public
class
JwtTokenRedisVo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1831633309466775223L
;
private
static
final
long
serialVersionUID
=
1831633309466775223L
;
private
String
type
;
/**
/**
* 登录ip
* 登录ip
*/
*/
...
...
framework/src/main/java/io/geekidea/springbootplus/framework/util/LoginUtil.java
View file @
543097ed
...
@@ -16,7 +16,6 @@
...
@@ -16,7 +16,6 @@
package
io
.
geekidea
.
springbootplus
.
framework
.
util
;
package
io
.
geekidea
.
springbootplus
.
framework
.
util
;
import
io.geekidea.springbootplus.config.constant.CommonRedisKey
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtTokenUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtUtil
;
import
io.geekidea.springbootplus.framework.shiro.util.JwtUtil
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
import
io.geekidea.springbootplus.framework.shiro.vo.LoginSysUserRedisVo
;
...
@@ -55,7 +54,11 @@ public class LoginUtil {
...
@@ -55,7 +54,11 @@ public class LoginUtil {
if
(
StringUtils
.
isBlank
(
username
))
{
if
(
StringUtils
.
isBlank
(
username
))
{
return
null
;
return
null
;
}
}
return
(
LoginSysUserRedisVo
)
redisTemplate
.
opsForValue
().
get
(
String
.
format
(
CommonRedisKey
.
LOGIN_USER
,
username
));
// return (LoginSysUserRedisVo) redisTemplate.opsForValue().get(String.format(CommonRedisKey.LOGIN_USER, username));
LoginSysUserRedisVo
loginSysUserRedisVo
=
new
LoginSysUserRedisVo
();
loginSysUserRedisVo
.
setUsername
(
username
);
return
loginSysUserRedisVo
;
}
}
/**
/**
...
...
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