Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
V
volunteer_service
Project
Project
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
licc
volunteer_service
Commits
9815f182
Commit
9815f182
authored
Apr 09, 2021
by
cy
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
03a0d007
97402e78
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
150 additions
and
81 deletions
+150
-81
RedisConfig.java
...src/main/java/cn/wisenergy/common/config/RedisConfig.java
+2
-2
SerializeUtils.java
.../main/java/cn/wisenergy/common/config/SerializeUtils.java
+82
-0
UserLoginServiceImpl.java
...a/cn/wisenergy/service/app/impl/UserLoginServiceImpl.java
+4
-2
KickoutSessionControlFilter.java
...ergy/service/shir/filter/KickoutSessionControlFilter.java
+62
-77
No files found.
wisenergy-common/src/main/java/cn/wisenergy/common/config/RedisConfig.java
View file @
9815f182
...
@@ -21,8 +21,8 @@ public class RedisConfig {
...
@@ -21,8 +21,8 @@ public class RedisConfig {
RedisTemplate
<
String
,
Object
>
redisTemplate
=
new
RedisTemplate
<>();
RedisTemplate
<
String
,
Object
>
redisTemplate
=
new
RedisTemplate
<>();
redisTemplate
.
setKeySerializer
(
new
StringRedisSerializer
());
redisTemplate
.
setKeySerializer
(
new
StringRedisSerializer
());
redisTemplate
.
setHashKeySerializer
(
new
StringRedisSerializer
());
redisTemplate
.
setHashKeySerializer
(
new
StringRedisSerializer
());
redisTemplate
.
setHashValueSerializer
(
new
S
tringRedisSerializer
());
redisTemplate
.
setHashValueSerializer
(
new
S
erializeUtils
());
redisTemplate
.
setValueSerializer
(
new
S
tringRedisSerializer
());
redisTemplate
.
setValueSerializer
(
new
S
erializeUtils
());
redisTemplate
.
setConnectionFactory
(
factory
);
redisTemplate
.
setConnectionFactory
(
factory
);
return
redisTemplate
;
return
redisTemplate
;
}
}
...
...
wisenergy-common/src/main/java/cn/wisenergy/common/config/SerializeUtils.java
0 → 100644
View file @
9815f182
package
cn
.
wisenergy
.
common
.
config
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.data.redis.serializer.RedisSerializer
;
import
org.springframework.data.redis.serializer.SerializationException
;
import
java.io.*
;
/**
* @author: nh
* @date: 2021/04/08
* @description: redis的value序列化工具
*/
public
class
SerializeUtils
implements
RedisSerializer
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
SerializeUtils
.
class
);
public
static
boolean
isEmpty
(
byte
[]
data
)
{
return
(
data
==
null
||
data
.
length
==
0
);
}
/**
* 序列化
*
* @param object
* @return
* @throws SerializationException
*/
@Override
public
byte
[]
serialize
(
Object
object
)
throws
SerializationException
{
byte
[]
result
=
null
;
if
(
object
==
null
)
{
return
new
byte
[
0
];
}
try
(
ByteArrayOutputStream
byteStream
=
new
ByteArrayOutputStream
(
128
);
ObjectOutputStream
objectOutputStream
=
new
ObjectOutputStream
(
byteStream
)
)
{
if
(!(
object
instanceof
Serializable
))
{
throw
new
IllegalArgumentException
(
SerializeUtils
.
class
.
getSimpleName
()
+
" requires a Serializable payload "
+
"but received an object of type ["
+
object
.
getClass
().
getName
()
+
"]"
);
}
objectOutputStream
.
writeObject
(
object
);
objectOutputStream
.
flush
();
result
=
byteStream
.
toByteArray
();
}
catch
(
Exception
ex
)
{
logger
.
error
(
"Failed to serialize"
,
ex
);
}
return
result
;
}
/**
* 反序列化
*
* @param bytes
* @return
* @throws SerializationException
*/
@Override
public
Object
deserialize
(
byte
[]
bytes
)
throws
SerializationException
{
Object
result
=
null
;
if
(
isEmpty
(
bytes
))
{
return
null
;
}
try
(
ByteArrayInputStream
byteStream
=
new
ByteArrayInputStream
(
bytes
);
ObjectInputStream
objectInputStream
=
new
ObjectInputStream
(
byteStream
)
)
{
result
=
objectInputStream
.
readObject
();
}
catch
(
Exception
e
)
{
logger
.
error
(
"Failed to deserialize"
,
e
);
}
return
result
;
}
}
\ No newline at end of file
wisenergy-service/src/main/java/cn/wisenergy/service/app/impl/UserLoginServiceImpl.java
View file @
9815f182
...
@@ -63,6 +63,9 @@ public class UserLoginServiceImpl extends ServiceImpl<UsersMapper, User> impleme
...
@@ -63,6 +63,9 @@ public class UserLoginServiceImpl extends ServiceImpl<UsersMapper, User> impleme
@Autowired
@Autowired
private
RedisService
redisService
;
private
RedisService
redisService
;
@Autowired
private
KickoutSessionControlFilter
kickoutSessionControlFilter
;
//VIP客户初始密码
//VIP客户初始密码
private
static
final
String
PASSWORD
=
"123456"
;
private
static
final
String
PASSWORD
=
"123456"
;
...
@@ -206,8 +209,7 @@ public class UserLoginServiceImpl extends ServiceImpl<UsersMapper, User> impleme
...
@@ -206,8 +209,7 @@ public class UserLoginServiceImpl extends ServiceImpl<UsersMapper, User> impleme
UserToken
userToken
=
new
UserToken
(
userVo
.
getPhone
(),
credentialsSalt
,
USER_LOGIN_TYPE
);
UserToken
userToken
=
new
UserToken
(
userVo
.
getPhone
(),
credentialsSalt
,
USER_LOGIN_TYPE
);
try
{
try
{
subject
.
login
(
userToken
);
subject
.
login
(
userToken
);
KickoutSessionControlFilter
kitOut
=
new
KickoutSessionControlFilter
();
kickoutSessionControlFilter
.
changeSession
(
1
);
kitOut
.
changeSession
(
1
);
//3、构造返回参数
//3、构造返回参数
UserInfoVo
userInfoVo
=
new
UserInfoVo
();
UserInfoVo
userInfoVo
=
new
UserInfoVo
();
userInfoVo
.
setUserId
(
user
.
getId
());
userInfoVo
.
setUserId
(
user
.
getId
());
...
...
wisenergy-service/src/main/java/cn/wisenergy/service/shir/filter/KickoutSessionControlFilter.java
View file @
9815f182
package
cn
.
wisenergy
.
service
.
shir
.
filter
;
package
cn
.
wisenergy
.
service
.
shir
.
filter
;
import
cn.wisenergy.common.utils.exception.Result
;
import
cn.wisenergy.model.app.AccountInfo
;
import
cn.wisenergy.model.app.AccountInfo
;
import
cn.wisenergy.model.app.Staff
;
import
cn.wisenergy.model.app.Staff
;
import
cn.wisenergy.model.app.User
;
import
cn.wisenergy.model.app.User
;
...
@@ -8,16 +9,22 @@ import com.alibaba.fastjson.JSON;
...
@@ -8,16 +9,22 @@ import com.alibaba.fastjson.JSON;
import
com.alibaba.fastjson.serializer.SerializerFeature
;
import
com.alibaba.fastjson.serializer.SerializerFeature
;
import
com.itextpdf.text.log.Logger
;
import
com.itextpdf.text.log.Logger
;
import
com.itextpdf.text.log.LoggerFactory
;
import
com.itextpdf.text.log.LoggerFactory
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.lang.exception.ExceptionUtils
;
import
org.apache.shiro.SecurityUtils
;
import
org.apache.shiro.SecurityUtils
;
import
org.apache.shiro.cache.Cache
;
import
org.apache.shiro.cache.Cache
;
import
org.apache.shiro.cache.CacheManager
;
import
org.apache.shiro.session.Session
;
import
org.apache.shiro.session.Session
;
import
org.apache.shiro.session.mgt.DefaultSessionKey
;
import
org.apache.shiro.session.mgt.DefaultSessionKey
;
import
org.apache.shiro.subject.Subject
;
import
org.apache.shiro.subject.Subject
;
import
org.apache.shiro.web.filter.AccessControlFilter
;
import
org.apache.shiro.web.filter.AccessControlFilter
;
import
org.apache.shiro.cache.CacheManager
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.io.PrintWriter
;
import
java.io.Serializable
;
import
java.io.Serializable
;
...
@@ -25,8 +32,9 @@ import java.util.Deque;
...
@@ -25,8 +32,9 @@ import java.util.Deque;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.LinkedList
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.concurrent.TimeUnit
;
public
class
KickoutSessionControlFilter
extends
AccessControlFilter
{
public
class
KickoutSessionControlFilter
extends
AccessControlFilter
{
private
final
Logger
logger
=
LoggerFactory
.
getLogger
(
KickoutSessionControlFilter
.
class
);
private
final
Logger
logger
=
LoggerFactory
.
getLogger
(
KickoutSessionControlFilter
.
class
);
private
boolean
kickoutAfter
=
false
;
//踢出之前登录的/之后登录的用户 默认踢出之前登录的用户
private
boolean
kickoutAfter
=
false
;
//踢出之前登录的/之后登录的用户 默认踢出之前登录的用户
private
int
maxSession
=
1
;
//同一个帐号最大会话数 默认1
private
int
maxSession
=
1
;
//同一个帐号最大会话数 默认1
...
@@ -34,6 +42,15 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
...
@@ -34,6 +42,15 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
private
MySessionManager
sessionManager
;
private
MySessionManager
sessionManager
;
private
Cache
<
String
,
Deque
<
Serializable
>>
cache
;
private
Cache
<
String
,
Deque
<
Serializable
>>
cache
;
private
static
final
long
EXPIRE_TIME
=
30
*
60
;
private
static
final
String
DEFAULT_KICKOUT_CACHE_KEY_PREFIX
=
"shiro:cache:kickout:"
;
private
String
keyprefix
=
DEFAULT_KICKOUT_CACHE_KEY_PREFIX
;
@Autowired
private
RedisTemplate
redisTemplate
;
public
void
setKickoutAfter
(
boolean
kickoutAfter
)
{
public
void
setKickoutAfter
(
boolean
kickoutAfter
)
{
this
.
kickoutAfter
=
kickoutAfter
;
this
.
kickoutAfter
=
kickoutAfter
;
}
}
...
@@ -62,9 +79,8 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
...
@@ -62,9 +79,8 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
@Override
@Override
protected
boolean
onAccessDenied
(
ServletRequest
request
,
ServletResponse
response
)
throws
Exception
{
protected
boolean
onAccessDenied
(
ServletRequest
request
,
ServletResponse
response
)
throws
Exception
{
Subject
subject
=
getSubject
(
request
,
response
);
Subject
subject
=
getSubject
(
request
,
response
);
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
//
判断是否登录
//
没有登陆或没有设置“记住我”
if
(!
subject
.
isAuthenticated
()
&&
!
subject
.
isRemembered
())
{
if
(!
subject
.
isAuthenticated
()
&&
!
subject
.
isRemembered
())
{
return
true
;
return
true
;
}
}
...
@@ -75,71 +91,26 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
...
@@ -75,71 +91,26 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
//5分钟
//5分钟
session
.
setTimeout
(
300000
);
session
.
setTimeout
(
300000
);
Serializable
sessionId
=
null
;
Serializable
sessionId
=
session
.
getId
();
String
username
=
null
;
Integer
userId
=
null
;
// Deque<Serializable> deque = null;
try
{
try
{
//客户端
//客户端
User
user
=
(
User
)
SecurityUtils
.
getSubject
().
getPrincipal
();
User
user
=
(
User
)
SecurityUtils
.
getSubject
().
getPrincipal
();
username
=
user
.
getPhone
();
userId
=
user
.
getId
();
sessionId
=
session
.
getId
();
//读取缓存,没有就存入
//deque = cache.get(username);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
try
{
try
{
//管理端
//管理端
sessionId
=
session
.
getId
();
AccountInfo
accountInfo
=
(
AccountInfo
)
SecurityUtils
.
getSubject
().
getPrincipal
();
AccountInfo
accountInfo
=
(
AccountInfo
)
SecurityUtils
.
getSubject
().
getPrincipal
();
username
=
accountInfo
.
getUserName
();
userId
=
accountInfo
.
getId
();
//读取缓存,没有就存入
//deque = cache.get(username);
}
catch
(
Exception
en
)
{
}
catch
(
Exception
en
)
{
//员工端
//员工端
Staff
staff
=
(
Staff
)
SecurityUtils
.
getSubject
().
getPrincipal
();
Staff
staff
=
(
Staff
)
SecurityUtils
.
getSubject
().
getPrincipal
();
username
=
staff
.
getLoginName
();
userId
=
staff
.
getId
();
sessionId
=
session
.
getId
();
//读取缓存,没有就存入
//deque = cache.get(username);
}
}
/* //如果此用户没有session队列,也就是还没有登录过,缓存中没有,就new一个空队列,不然deque对象为空,会报空指针
if (deque == null) {
deque = new LinkedList<>();
}
}
//如果队列里没有此sessionId,且用户没有被踢出;放入队列
if (!deque.contains(sessionId) && session.getAttribute("kickout") == null) {
//将sessionId存入队列
deque.push(sessionId);
//将用户的sessionId队列缓存
cache.put(username, deque);
}
}
//如果队列里的sessionId数超出最大会话数,开始踢人
while (deque.size() > maxSession) {
Serializable kickoutSessionId;
if (kickoutAfter) { //如果踢出后者
kickoutSessionId = deque.removeFirst();
//踢出后再更新下缓存队列
} else { //否则踢出前者
kickoutSessionId = deque.removeLast();
//踢出后再更新下缓存队列
}
cache.put(username, deque);
try {
//获取被踢出的sessionId的session对象
DefaultSessionKey defaultSessionKey = new DefaultSessionKey(kickoutSessionId);
Session kickoutSession = sessionManager.getSession(defaultSessionKey);
//Session kickoutSession = (Session) sessionManager.getSession(String.valueOf(new DefaultSessionKey(kickoutSessionId)));
if (kickoutSession != null) {
//设置会话的kickout属性表示踢出了
kickoutSession.setAttribute("kickout", true);
}
} catch (Exception e) {
}
}*/
//如果被踢出了,直接退出,重定向到踢出后的地址
//如果被踢出了,直接退出,重定向到踢出后的地址
if
(
session
.
getAttribute
(
"kickout"
)
!=
null
)
{
if
(
session
.
getAttribute
(
"kickout"
)
!=
null
)
{
logger
.
info
(
"------"
+
"踢出用户"
+
user
name
+
"登录sessionId="
+
sessionId
+
"------"
);
logger
.
info
(
"------"
+
"踢出用户"
+
user
Id
+
"登录sessionId="
+
sessionId
+
"------"
);
//会话被踢出了
//会话被踢出了
try
{
try
{
//退出登录
//退出登录
...
@@ -174,49 +145,35 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
...
@@ -174,49 +145,35 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
Subject
subject
=
SecurityUtils
.
getSubject
();
Subject
subject
=
SecurityUtils
.
getSubject
();
Session
session
=
subject
.
getSession
();
Session
session
=
subject
.
getSession
();
session
.
setTimeout
(
300000
);
session
.
setTimeout
(
300000
);
Serializable
sessionId
=
session
.
getId
();
Serializable
sessionId
=
session
.
getId
();
String
username
=
null
;
Integer
userId
=
null
;
Deque
<
Serializable
>
deque
=
null
;
if
(
type
==
1
){
if
(
type
==
1
){
User
user
=(
User
)
subject
.
getPrincipal
();
User
user
=(
User
)
subject
.
getPrincipal
();
user
name
=
user
.
getPhone
();
user
Id
=
user
.
getId
();
}
else
if
(
type
==
2
){
}
else
if
(
type
==
2
){
AccountInfo
account
=(
AccountInfo
)
subject
.
getPrincipal
();
AccountInfo
account
=(
AccountInfo
)
subject
.
getPrincipal
();
user
name
=
account
.
getUserName
();
user
Id
=
account
.
getId
();
}
else
{
}
else
{
Staff
staff
=(
Staff
)
subject
.
getPrincipal
();
Staff
staff
=(
Staff
)
subject
.
getPrincipal
();
user
name
=
staff
.
getLoginName
();
user
Id
=
staff
.
getId
();
}
}
//读取缓存,没有就存入
//读取缓存,没有就存入
deque
=
cache
.
get
(
username
);
Deque
<
Serializable
>
deque
=(
Deque
<
Serializable
>)
redisTemplate
.
opsForValue
().
get
(
getRedisKickoutKey
(
userId
)
);
//如果此用户没有session队列,也就是还没有登录过,缓存中没有,就new一个空队列,不然deque对象为空,会报空指针
//如果此用户没有session队列,也就是还没有登录过,缓存中没有,就new一个空队列,不然deque对象为空,会报空指针
if
(
deque
==
null
)
{
if
(
deque
==
null
||
deque
.
size
()==
0
)
{
deque
=
new
LinkedList
<>();
deque
=
new
LinkedList
<>();
}
}
//如果队列里没有此sessionId,且用户没有被踢出;放入队列
//如果队列里没有此sessionId,且用户没有被踢出;放入队列
if
(!
deque
.
contains
(
sessionId
)
&&
session
.
getAttribute
(
"kickout"
)
==
null
)
{
if
(!
deque
.
contains
(
sessionId
)
&&
session
.
getAttribute
(
"kickout"
)
==
null
)
{
//将sessionId存入队列
//将sessionId存入队列
deque
.
push
(
sessionId
);
deque
.
push
(
sessionId
);
//将用户的sessionId队列缓存
cache
.
put
(
username
,
deque
);
}
}
//如果队列里的sessionId数超出最大会话数,开始踢人
//如果队列里的sessionId数超出最大会话数,开始踢人
while
(
deque
.
size
()
>
maxSession
)
{
while
(
deque
.
size
()
>
maxSession
)
{
Serializable
kickoutSessionId
;
Serializable
kickoutSessionId
=
kickoutAfter
?
deque
.
removeFirst
():
deque
.
removeLast
();
if
(
kickoutAfter
)
{
//如果踢出后者
kickoutSessionId
=
deque
.
removeFirst
();
//踢出后再更新下缓存队列
}
else
{
//否则踢出前者
kickoutSessionId
=
deque
.
removeLast
();
//踢出后再更新下缓存队列
}
cache
.
put
(
username
,
deque
);
try
{
try
{
//获取被踢出的sessionId的session对象
//获取被踢出的sessionId的session对象
DefaultSessionKey
defaultSessionKey
=
new
DefaultSessionKey
(
kickoutSessionId
);
Session
kickoutSession
=
sessionManager
.
getSession
(
new
DefaultSessionKey
(
kickoutSessionId
));
Session
kickoutSession
=
sessionManager
.
getSession
(
defaultSessionKey
);
//Session kickoutSession = (Session) sessionManager.getSession(String.valueOf(new DefaultSessionKey(kickoutSessionId)));
if
(
kickoutSession
!=
null
)
{
if
(
kickoutSession
!=
null
)
{
//设置会话的kickout属性表示踢出了
//设置会话的kickout属性表示踢出了
kickoutSession
.
setAttribute
(
"kickout"
,
true
);
kickoutSession
.
setAttribute
(
"kickout"
,
true
);
...
@@ -224,6 +181,34 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
...
@@ -224,6 +181,34 @@ public class KickoutSessionControlFilter extends AccessControlFilter {
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
}
}
}
}
// 更新redis中的用户登录队列
redisTemplate
.
opsForValue
().
set
(
getRedisKickoutKey
(
userId
),
deque
,
EXPIRE_TIME
,
TimeUnit
.
SECONDS
);
}
String
getRedisKickoutKey
(
Integer
userId
)
{
return
keyprefix
+
userId
;
}
// 抛出未登录异常
private
void
thrLogoutException
(
HttpServletResponse
response
){
PrintWriter
writer
=
null
;
try
{
Result
result
=
new
Result
();
result
.
setResult
(
Result
.
RESULT_FLG
.
FAIL
.
getValue
());
// result.setErrorCode();
// result.setErrorMsg();
response
.
setContentType
(
"application/json; charset=UTF-8"
);
writer
=
response
.
getWriter
();
writer
.
write
(
JSON
.
toJSONString
(
result
));
writer
.
flush
();
}
catch
(
Exception
e
)
{
IOUtils
.
closeQuietly
(
writer
);
logger
.
error
(
"接口异常:{}"
+
ExceptionUtils
.
getFullStackTrace
(
e
));
}
finally
{
if
(
writer
!=
null
)
{
writer
.
close
();
}
}
}
}
...
...
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