Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
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
aa8985b0
Commit
aa8985b0
authored
Apr 10, 2021
by
xc
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shiro限定并发登录人数
parent
3dacc61f
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
24 additions
and
1115 deletions
+24
-1115
AccountSerivceImpl.java
...ava/cn/wisenergy/service/app/impl/AccountSerivceImpl.java
+1
-1
UserLoginServiceImpl.java
...a/cn/wisenergy/service/app/impl/UserLoginServiceImpl.java
+2
-2
ShiroConfig.java
...in/java/cn/wisenergy/service/shir/config/ShiroConfig.java
+0
-1
KickoutSessionControlFilter.java
...ergy/service/shir/filter/KickoutSessionControlFilter.java
+21
-38
MySessionManager.java
...in/java/cn/wisenergy/web/shir/cache/MySessionManager.java
+0
-39
ShiroConfig.java
...c/main/java/cn/wisenergy/web/shir/config/ShiroConfig.java
+0
-256
AuthenticationFilter.java
...va/cn/wisenergy/web/shir/filter/AuthenticationFilter.java
+0
-72
KickoutSessionControlFilter.java
...isenergy/web/shir/filter/KickoutSessionControlFilter.java
+0
-180
AdminRealm.java
...src/main/java/cn/wisenergy/web/shir/realm/AdminRealm.java
+0
-47
CodeRealm.java
.../src/main/java/cn/wisenergy/web/shir/realm/CodeRealm.java
+0
-56
StaffRealm.java
...src/main/java/cn/wisenergy/web/shir/realm/StaffRealm.java
+0
-45
UserRealm.java
.../src/main/java/cn/wisenergy/web/shir/realm/UserRealm.java
+0
-50
SessionUntil.java
...rc/main/java/cn/wisenergy/web/shir/util/SessionUntil.java
+0
-97
ShiroUtils.java
.../src/main/java/cn/wisenergy/web/shir/util/ShiroUtils.java
+0
-141
SpringUtil.java
.../src/main/java/cn/wisenergy/web/shir/util/SpringUtil.java
+0
-42
UserModularRealmAuthenticator.java
...isenergy/web/shir/util/UserModularRealmAuthenticator.java
+0
-48
No files found.
wisenergy-service/src/main/java/cn/wisenergy/service/app/impl/AccountSerivceImpl.java
View file @
aa8985b0
...
...
@@ -67,7 +67,7 @@ public class AccountSerivceImpl implements AccountSerivce {
//返回数据
try
{
subject
.
login
(
userToken
);
kickoutSessionControlFilter
.
changeSession
(
1
);
kickoutSessionControlFilter
.
changeSession
(
2
);
AccountDto
accountDto
=
new
AccountDto
();
AccountInfo
info
=(
AccountInfo
)
SecurityUtils
.
getSubject
().
getPrincipal
();
accountDto
.
setId
(
info
.
getId
());
...
...
wisenergy-service/src/main/java/cn/wisenergy/service/app/impl/UserLoginServiceImpl.java
View file @
aa8985b0
...
...
@@ -161,7 +161,7 @@ public class UserLoginServiceImpl extends ServiceImpl<UsersMapper, User> impleme
UserToken
userToken
=
new
UserToken
(
userVo
.
getPhone
(),
userVo
.
getCode
(),
CODE_LOGIN_TYPE
);
try
{
subject
.
login
(
userToken
);
kickoutSessionControlFilter
.
changeSession
(
2
);
kickoutSessionControlFilter
.
changeSession
(
1
);
//3、构造返回参数
UserInfoVo
userInfoVo
=
new
UserInfoVo
();
userInfoVo
.
setUserId
(
user
.
getId
());
...
...
@@ -209,7 +209,7 @@ public class UserLoginServiceImpl extends ServiceImpl<UsersMapper, User> impleme
UserToken
userToken
=
new
UserToken
(
userVo
.
getPhone
(),
credentialsSalt
,
USER_LOGIN_TYPE
);
try
{
subject
.
login
(
userToken
);
kickoutSessionControlFilter
.
changeSession
(
2
);
kickoutSessionControlFilter
.
changeSession
(
1
);
//3、构造返回参数
UserInfoVo
userInfoVo
=
new
UserInfoVo
();
userInfoVo
.
setUserId
(
user
.
getId
());
...
...
wisenergy-service/src/main/java/cn/wisenergy/service/shir/config/ShiroConfig.java
View file @
aa8985b0
...
...
@@ -227,7 +227,6 @@ public class ShiroConfig {
@Bean
public
KickoutSessionControlFilter
kickoutSessionControlFilter
()
{
KickoutSessionControlFilter
kickoutSessionControlFilter
=
new
KickoutSessionControlFilter
();
kickoutSessionControlFilter
.
setCacheManager
(
cacheManagers
());
kickoutSessionControlFilter
.
setSessionManager
(
sessionManager
());
kickoutSessionControlFilter
.
setKickoutAfter
(
false
);
kickoutSessionControlFilter
.
setMaxSession
(
1
);
...
...
wisenergy-service/src/main/java/cn/wisenergy/service/shir/filter/KickoutSessionControlFilter.java
View file @
aa8985b0
...
...
@@ -37,14 +37,16 @@ import java.util.concurrent.TimeUnit;
@Slf4j
public
class
KickoutSessionControlFilter
extends
AccessControlFilter
{
private
final
Logger
logger
=
LoggerFactory
.
getLogger
(
KickoutSessionControlFilter
.
class
);
private
boolean
kickoutAfter
=
false
;
//踢出之前登录的/之后登录的用户 默认踢出之前登录的用户
private
int
maxSession
=
1
;
//同一个帐号最大会话数 默认1
private
MySessionManager
sessionManager
;
private
Cache
<
String
,
Deque
<
Serializable
>>
cache
;
private
static
final
long
EXPIRE_TIME
=
30
*
60
;
//设置session超时时长,30分钟(1800000毫秒)
//session.setTimeout(1800000);
//5分钟
private
static
final
long
EXPIRE_TIME
=
5
*
60
;
private
static
final
String
DEFAULT_KICKOUT_CACHE_KEY_PREFIX
=
"shiro:cache:kickout:"
;
...
...
@@ -65,12 +67,6 @@ public class KickoutSessionControlFilter extends AccessControlFilter{
this
.
sessionManager
=
sessionManager
;
}
//设置Cache的key的前缀
public
void
setCacheManager
(
CacheManager
cacheManager
)
{
this
.
cache
=
cacheManager
.
getCache
(
"shiro_redis_cache"
);
}
@Override
protected
boolean
isAccessAllowed
(
ServletRequest
request
,
ServletResponse
response
,
Object
mappedValue
)
throws
Exception
{
//如果是小程序,就放行
...
...
@@ -83,18 +79,15 @@ public class KickoutSessionControlFilter extends AccessControlFilter{
log
.
info
(
"KickoutSessionControlFilter Not Login begin......."
);
Subject
subject
=
getSubject
(
request
,
response
);
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
HttpServletResponse
httpServletResponse
=
(
HttpServletResponse
)
response
;
// 没有登陆或没有设置“记住我”
if
(!
subject
.
isAuthenticated
()
&&
!
subject
.
isRemembered
())
{
log
.
info
(
"KickoutSessionControlFilter isAuthenticated and isRemembered return true ......."
);
return
true
;
log
.
info
(
"KickoutSessionControlFilter isAuthenticated and isRemembered Please login first ......."
);
// 没有登陆,抛出异常
thrLogoutException
(
httpServletResponse
,
"1001"
,
"Please login first"
);
return
false
;
}
Session
session
=
subject
.
getSession
();
//设置session超时时长,30分钟(1800000毫秒)
//session.setTimeout(1800000);
//5分钟
session
.
setTimeout
(
300000
);
Serializable
sessionId
=
session
.
getId
();
Integer
userId
=
null
;
try
{
...
...
@@ -112,7 +105,7 @@ public class KickoutSessionControlFilter extends AccessControlFilter{
userId
=
staff
.
getId
();
}
}
log
.
info
(
"KickoutSessionControlFilter 如果被踢出了,直接退出,重定向到踢出后的地址-----"
);
log
.
info
(
"KickoutSessionControlFilter 如果被踢出了,直接退出,重定向到踢出后的地址-----
返回1002
"
);
//如果被踢出了,直接退出,重定向到踢出后的地址
if
(
session
.
getAttribute
(
"kickout"
)
!=
null
)
{
log
.
info
(
"------"
+
"踢出用户"
+
userId
+
"登录sessionId="
+
sessionId
+
"------"
);
...
...
@@ -120,33 +113,23 @@ public class KickoutSessionControlFilter extends AccessControlFilter{
try
{
//退出登录
subject
.
logout
();
thrLogoutException
(
httpServletResponse
,
"1002"
,
"您已经在其他地方登录,请重新登录。如有疑问请联系管理员!"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
saveRequest
(
request
);
map
.
put
(
"status"
,
"1002"
);
map
.
put
(
"message"
,
"您已经在其他地方登录,请重新登录。如有疑问请联系管理员!"
);
out
(
response
,
map
);
return
false
;
}
log
.
info
(
"KickoutSessionControlFilter Not Login end......."
);
return
true
;
}
private
void
out
(
ServletResponse
response
,
Map
<
String
,
Object
>
map
)
throws
IOException
{
response
.
setContentType
(
"text/json"
);
//设置字符集为'UTF-8'
response
.
setCharacterEncoding
(
"UTF-8"
);
PrintWriter
out
=
response
.
getWriter
();
out
.
write
(
JSON
.
toJSONString
(
map
,
SerializerFeature
.
WriteMapNullValue
));
out
.
flush
();
out
.
close
();
}
public
boolean
isFilter
(
HttpServletRequest
request
)
{
return
null
!=
request
.
getHeader
(
"identity"
)
&&
request
.
getHeader
(
"identity"
).
equals
(
"miniprogram"
);
String
url
=
request
.
getRequestURI
();
boolean
result
=
null
!=
request
.
getHeader
(
"identity"
)
&&
request
.
getHeader
(
"identity"
).
equals
(
"miniprogram"
);
boolean
result1
=
url
.
indexOf
(
"/login"
)!=-
1
;
return
result
||
result1
;
}
public
void
changeSession
(
int
type
){
log
.
info
(
"KickoutSessionControlFilter changeSession begin.......type : "
+
type
);
Subject
subject
=
SecurityUtils
.
getSubject
();
...
...
@@ -194,18 +177,18 @@ public class KickoutSessionControlFilter extends AccessControlFilter{
log
.
info
(
"KickoutSessionControlFilter changeSession end......."
);
}
String
getRedisKickoutKey
(
Integer
userId
)
{
private
String
getRedisKickoutKey
(
Integer
userId
)
{
return
keyprefix
+
userId
;
}
// 抛出未登录异常
private
void
thrLogoutException
(
HttpServletResponse
response
){
private
void
thrLogoutException
(
HttpServletResponse
response
,
String
ErrorCode
,
String
ErrorMsg
){
PrintWriter
writer
=
null
;
try
{
Result
result
=
new
Result
();
result
.
setResult
(
Result
.
RESULT_FLG
.
FAIL
.
getValue
());
// result.setErrorCode(
);
// result.setErrorMsg(
);
result
.
setErrorCode
(
ErrorCode
);
result
.
setErrorMsg
(
ErrorMsg
);
response
.
setContentType
(
"application/json; charset=UTF-8"
);
writer
=
response
.
getWriter
();
writer
.
write
(
JSON
.
toJSONString
(
result
));
...
...
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/cache/MySessionManager.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
cache
;
import
org.apache.commons.lang.StringUtils
;
import
org.apache.shiro.web.servlet.ShiroHttpServletRequest
;
import
org.apache.shiro.web.session.mgt.DefaultWebSessionManager
;
import
org.apache.shiro.web.util.WebUtils
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
java.io.Serializable
;
public
class
MySessionManager
extends
DefaultWebSessionManager
{
//前端传递sessionid参数名称
private
static
final
String
AUTHORIZATION
=
"sessionId"
;
private
static
final
String
REFERENCED_SESSION_ID_SOURCE
=
"Stateless request"
;
public
MySessionManager
()
{
super
();
}
@Override
protected
Serializable
getSessionId
(
ServletRequest
request
,
ServletResponse
response
)
{
String
id
=
WebUtils
.
toHttp
(
request
).
getHeader
(
AUTHORIZATION
);
//如果请求头中有 token 则其值为sessionId
if
(!
StringUtils
.
isEmpty
(
id
))
{
request
.
setAttribute
(
ShiroHttpServletRequest
.
REFERENCED_SESSION_ID_SOURCE
,
REFERENCED_SESSION_ID_SOURCE
);
request
.
setAttribute
(
ShiroHttpServletRequest
.
REFERENCED_SESSION_ID
,
id
);
request
.
setAttribute
(
ShiroHttpServletRequest
.
REFERENCED_SESSION_ID_IS_VALID
,
Boolean
.
TRUE
);
return
id
;
}
else
{
//否则按默认规则从cookie取sessionId
return
super
.
getSessionId
(
request
,
response
);
}
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/config/ShiroConfig.java
deleted
100644 → 0
View file @
3dacc61f
This diff is collapsed.
Click to expand it.
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/filter/AuthenticationFilter.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
filter
;
import
com.alibaba.fastjson.JSONObject
;
import
org.apache.shiro.web.filter.authc.FormAuthenticationFilter
;
import
org.springframework.http.HttpStatus
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* 跨域配置拦截器,继承FormAuthenticationFilter
*/
public
class
AuthenticationFilter
extends
FormAuthenticationFilter
{
@Override
protected
boolean
onAccessDenied
(
ServletRequest
request
,
ServletResponse
response
)
throws
Exception
{
// 错误异常提示
HttpServletResponse
httpResponse
=
(
HttpServletResponse
)
response
;
HttpServletRequest
httpRequest
=
(
HttpServletRequest
)
request
;
String
sessionId
=
((
HttpServletRequest
)
request
).
getHeader
(
"sessionId"
);
if
(
sessionId
==
null
)
{
setHeader
(
httpRequest
,
httpResponse
);
httpResponse
.
setCharacterEncoding
(
"UTF-8"
);
httpResponse
.
setContentType
(
"application/json"
);
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"status"
,
"1001"
);
map
.
put
(
"message"
,
"登录已超时,请重新登录!"
);
httpResponse
.
getWriter
().
write
(
JSONObject
.
toJSONString
(
map
));
return
false
;
}
else
{
return
true
;
}
}
/**
* 为response设置header,实现跨域
*/
private
void
setHeader
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
//跨域的header设置
response
.
setHeader
(
"Access-control-Allow-Origin"
,
request
.
getHeader
(
"Origin"
));
response
.
setHeader
(
"Access-Control-Allow-Methods"
,
request
.
getMethod
());
response
.
setHeader
(
"Access-Control-Allow-Credentials"
,
"true"
);
response
.
setHeader
(
"Access-Control-Allow-Headers"
,
request
.
getHeader
(
"Access-Control-Request-Headers"
));
//防止乱码,适用于传输JSON数据
//Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild
response
.
setHeader
(
"Content-Type"
,
"application/json;charset=UTF-8"
);
response
.
setStatus
(
HttpStatus
.
OK
.
value
());
}
@Override
protected
boolean
isAccessAllowed
(
ServletRequest
request
,
ServletResponse
response
,
Object
mappedValue
)
{
if
(
request
instanceof
HttpServletRequest
)
{
if
(((
HttpServletRequest
)
request
).
getMethod
().
toUpperCase
().
equals
(
"OPTIONS"
))
{
return
true
;
}
}
//小程序放行
if
(
isFilter
((
HttpServletRequest
)
request
)){
return
true
;
}
return
super
.
isAccessAllowed
(
request
,
response
,
mappedValue
);
}
//判断请求头中是否带有identity(标识是小程序)
public
boolean
isFilter
(
HttpServletRequest
request
)
{
return
null
!=
request
.
getHeader
(
"identity"
)
&&
request
.
getHeader
(
"identity"
).
equals
(
"miniprogram"
);
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/filter/KickoutSessionControlFilter.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
filter
;
import
cn.wisenergy.model.app.AccountInfo
;
import
cn.wisenergy.model.app.Staff
;
import
cn.wisenergy.model.app.User
;
import
cn.wisenergy.web.shir.cache.MySessionManager
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.serializer.SerializerFeature
;
import
com.itextpdf.text.log.Logger
;
import
com.itextpdf.text.log.LoggerFactory
;
import
org.apache.logging.log4j.ThreadContext
;
import
org.apache.shiro.SecurityUtils
;
import
org.apache.shiro.cache.Cache
;
import
org.apache.shiro.cache.CacheManager
;
import
org.apache.shiro.session.ExpiredSessionException
;
import
org.apache.shiro.session.InvalidSessionException
;
import
org.apache.shiro.session.Session
;
import
org.apache.shiro.session.mgt.DefaultSessionKey
;
import
org.apache.shiro.session.mgt.SessionKey
;
import
org.apache.shiro.subject.PrincipalCollection
;
import
org.apache.shiro.subject.Subject
;
import
org.apache.shiro.web.filter.AccessControlFilter
;
import
org.springframework.web.servlet.mvc.support.RedirectAttributes
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.io.Serializable
;
import
java.util.Deque
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.Map
;
public
class
KickoutSessionControlFilter
extends
AccessControlFilter
{
private
final
Logger
logger
=
LoggerFactory
.
getLogger
(
KickoutSessionControlFilter
.
class
);
private
boolean
kickoutAfter
=
false
;
//踢出之前登录的/之后登录的用户 默认踢出之前登录的用户
private
int
maxSession
=
1
;
//同一个帐号最大会话数 默认1
private
MySessionManager
sessionManager
;
private
Cache
<
String
,
Deque
<
Serializable
>>
cache
;
public
void
setKickoutAfter
(
boolean
kickoutAfter
)
{
this
.
kickoutAfter
=
kickoutAfter
;
}
public
void
setMaxSession
(
int
maxSession
)
{
this
.
maxSession
=
maxSession
;
}
public
void
setSessionManager
(
MySessionManager
sessionManager
)
{
this
.
sessionManager
=
sessionManager
;
}
//设置Cache的key的前缀
/* public void setCacheManager(CacheManager cacheManager) {
this.cache = cacheManager.getCache("shiro_redis_cache");
}*/
@Override
protected
boolean
isAccessAllowed
(
ServletRequest
request
,
ServletResponse
response
,
Object
mappedValue
)
throws
Exception
{
//如果是小程序,就放行
boolean
filter
=
isFilter
((
HttpServletRequest
)
request
);
return
filter
;
}
@Override
protected
boolean
onAccessDenied
(
ServletRequest
request
,
ServletResponse
response
)
throws
Exception
{
Subject
subject
=
getSubject
(
request
,
response
);
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
//判断是否登录
if
(!
subject
.
isAuthenticated
()
&&
!
subject
.
isRemembered
())
{
return
true
;
}
Session
session
=
subject
.
getSession
();
//设置session超时时长,30分钟(1800000毫秒)
//session.setTimeout(1800000);
//5分钟
session
.
setTimeout
(
300000
);
Serializable
sessionId
=
null
;
String
username
=
null
;
// Deque<Serializable> deque = null;
try
{
//客户端
User
user
=
(
User
)
SecurityUtils
.
getSubject
().
getPrincipal
();
username
=
user
.
getPhone
();
sessionId
=
session
.
getId
();
//读取缓存,没有就存入
//deque = cache.get(username);
}
catch
(
Exception
e
)
{
try
{
//管理端
sessionId
=
session
.
getId
();
AccountInfo
accountInfo
=
(
AccountInfo
)
SecurityUtils
.
getSubject
().
getPrincipal
();
username
=
accountInfo
.
getUserName
();
//读取缓存,没有就存入
//deque = cache.get(username);
}
catch
(
Exception
en
)
{
//员工端
Staff
staff
=
(
Staff
)
SecurityUtils
.
getSubject
().
getPrincipal
();
username
=
staff
.
getLoginName
();
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
)
{
logger
.
info
(
"------"
+
"踢出用户"
+
username
+
"登录sessionId="
+
sessionId
+
"------"
);
//会话被踢出了
try
{
//退出登录
subject
.
logout
();
}
catch
(
Exception
e
)
{
}
saveRequest
(
request
);
map
.
put
(
"status"
,
"1002"
);
map
.
put
(
"message"
,
"您已经在其他地方登录,请重新登录。如有疑问请联系管理员!"
);
out
(
response
,
map
);
return
false
;
}
return
true
;
}
private
void
out
(
ServletResponse
response
,
Map
<
String
,
Object
>
map
)
throws
IOException
{
response
.
setContentType
(
"text/json"
);
//设置字符集为'UTF-8'
response
.
setCharacterEncoding
(
"UTF-8"
);
PrintWriter
out
=
response
.
getWriter
();
out
.
write
(
JSON
.
toJSONString
(
map
,
SerializerFeature
.
WriteMapNullValue
));
out
.
flush
();
out
.
close
();
}
public
boolean
isFilter
(
HttpServletRequest
request
)
{
return
null
!=
request
.
getHeader
(
"identity"
)
&&
request
.
getHeader
(
"identity"
).
equals
(
"miniprogram"
);
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/realm/AdminRealm.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
realm
;
import
cn.wisenergy.common.utils.Md5Util
;
import
cn.wisenergy.mapper.AccountMapper
;
import
cn.wisenergy.model.app.AccountInfo
;
import
cn.wisenergy.service.util.UserToken
;
import
cn.wisenergy.web.shir.util.SessionUntil
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
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.realm.AuthorizingRealm
;
import
org.apache.shiro.subject.PrincipalCollection
;
import
org.springframework.beans.factory.annotation.Autowired
;
public
class
AdminRealm
extends
AuthorizingRealm
{
@Autowired
private
AccountMapper
accountMapper
;
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
return
null
;
}
@Override
protected
AuthenticationInfo
doGetAuthenticationInfo
(
AuthenticationToken
token
)
throws
AuthenticationException
{
UserToken
userToken
=
(
UserToken
)
token
;
String
userName
=
userToken
.
getUsername
();
QueryWrapper
<
AccountInfo
>
queryWrapper
=
new
QueryWrapper
<>();
queryWrapper
.
eq
(
"user_name"
,
userName
);
queryWrapper
.
eq
(
"is_delete"
,
0
);
AccountInfo
accountInfo
=
accountMapper
.
selectOne
(
queryWrapper
);
if
(
accountInfo
==
null
)
{
return
null
;
}
String
password
=
Md5Util
.
digestMD5
(
accountInfo
.
getPassword
());
SimpleAuthenticationInfo
authenticationInfo
=
new
SimpleAuthenticationInfo
(
accountInfo
,
password
,
accountInfo
.
getUserName
()
);
SessionUntil
sessionUntil
=
new
SessionUntil
();
sessionUntil
.
changeSession
(
2
);
return
authenticationInfo
;
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/realm/CodeRealm.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
realm
;
import
cn.wisenergy.mapper.UsersMapper
;
import
cn.wisenergy.model.app.User
;
import
cn.wisenergy.model.enums.SourceType
;
import
cn.wisenergy.service.cache.RedisService
;
import
cn.wisenergy.service.common.CachePrefix
;
import
cn.wisenergy.service.common.Common
;
import
cn.wisenergy.service.util.UserToken
;
import
cn.wisenergy.web.shir.util.SessionUntil
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
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.realm.AuthorizingRealm
;
import
org.apache.shiro.subject.PrincipalCollection
;
import
org.springframework.beans.factory.annotation.Autowired
;
public
class
CodeRealm
extends
AuthorizingRealm
{
@Autowired
private
UsersMapper
usersMapper
;
@Autowired
private
RedisService
redisService
;
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
return
null
;
}
@Override
protected
AuthenticationInfo
doGetAuthenticationInfo
(
AuthenticationToken
token
)
throws
AuthenticationException
{
UserToken
userToken
=
(
UserToken
)
token
;
String
userName
=
userToken
.
getUsername
();
QueryWrapper
<
User
>
queryWrapper
=
new
QueryWrapper
<>();
queryWrapper
.
eq
(
"phone"
,
userName
);
queryWrapper
.
eq
(
"is_delete"
,
0
);
User
userInfo
=
usersMapper
.
selectOne
(
queryWrapper
);
if
(
userInfo
==
null
)
{
return
null
;
}
String
source
=
SourceType
.
getByCode
(
userInfo
.
getSource
());
//获取短信验证码key
String
key
=
CachePrefix
.
SMS_CODE
.
getPrefix
()
+
"_"
+
source
+
"_"
+
userInfo
.
getPhone
();
Object
obj
=
redisService
.
get
(
key
);
String
code
=
obj
.
toString
();
SimpleAuthenticationInfo
authenticationInfo
=
new
SimpleAuthenticationInfo
(
userInfo
,
code
,
userInfo
.
getPhone
()
);
SessionUntil
sessionUntil
=
new
SessionUntil
();
sessionUntil
.
changeSession
(
1
);
return
authenticationInfo
;
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/realm/StaffRealm.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
realm
;
import
cn.wisenergy.mapper.StaffMapper
;
import
cn.wisenergy.model.app.Staff
;
import
cn.wisenergy.service.util.UserToken
;
import
cn.wisenergy.web.shir.util.SessionUntil
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
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.realm.AuthorizingRealm
;
import
org.apache.shiro.subject.PrincipalCollection
;
import
org.springframework.beans.factory.annotation.Autowired
;
public
class
StaffRealm
extends
AuthorizingRealm
{
@Autowired
private
StaffMapper
staffMapper
;
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
return
null
;
}
@Override
protected
AuthenticationInfo
doGetAuthenticationInfo
(
AuthenticationToken
token
)
throws
AuthenticationException
{
UserToken
userToken
=
(
UserToken
)
token
;
String
userName
=
userToken
.
getUsername
();
QueryWrapper
<
Staff
>
queryWrapper
=
new
QueryWrapper
<>();
queryWrapper
.
eq
(
"login_name"
,
userName
);
queryWrapper
.
eq
(
"is_delete"
,
0
);
Staff
staff
=
staffMapper
.
selectOne
(
queryWrapper
);
if
(
staff
==
null
)
{
return
null
;
}
SimpleAuthenticationInfo
authenticationInfo
=
new
SimpleAuthenticationInfo
(
staff
,
staff
.
getPassword
(),
staff
.
getLoginName
()
);
SessionUntil
sessionUntil
=
new
SessionUntil
();
sessionUntil
.
changeSession
(
3
);
return
authenticationInfo
;
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/realm/UserRealm.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
realm
;
import
cn.wisenergy.mapper.UsersMapper
;
import
cn.wisenergy.model.app.User
;
import
cn.wisenergy.service.util.UserToken
;
import
cn.wisenergy.web.shir.util.SessionUntil
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
org.apache.shiro.SecurityUtils
;
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.realm.AuthorizingRealm
;
import
org.apache.shiro.subject.PrincipalCollection
;
import
org.apache.shiro.subject.Subject
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
java.io.Serializable
;
public
class
UserRealm
extends
AuthorizingRealm
{
@Autowired
private
UsersMapper
usersMapper
;
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principalCollection
)
{
return
null
;
}
@Override
protected
AuthenticationInfo
doGetAuthenticationInfo
(
AuthenticationToken
token
)
throws
AuthenticationException
{
UserToken
userToken
=
(
UserToken
)
token
;
String
userName
=
userToken
.
getUsername
();
//通过username从数据库中查找 User对象
QueryWrapper
<
User
>
queryWrapper
=
new
QueryWrapper
<>();
queryWrapper
.
eq
(
"phone"
,
userName
);
queryWrapper
.
eq
(
"is_delete"
,
0
);
User
userInfo
=
usersMapper
.
selectOne
(
queryWrapper
);
if
(
userInfo
==
null
)
{
return
null
;
}
SimpleAuthenticationInfo
authenticationInfo
=
new
SimpleAuthenticationInfo
(
userInfo
,
userInfo
.
getPassword
(),
userInfo
.
getPhone
()
);
return
authenticationInfo
;
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/util/SessionUntil.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
util
;
import
cn.wisenergy.model.app.AccountInfo
;
import
cn.wisenergy.model.app.Staff
;
import
cn.wisenergy.model.app.User
;
import
cn.wisenergy.web.shir.cache.MySessionManager
;
import
org.apache.shiro.SecurityUtils
;
import
org.apache.shiro.cache.Cache
;
import
org.apache.shiro.cache.CacheManager
;
import
org.apache.shiro.session.Session
;
import
org.apache.shiro.session.mgt.DefaultSessionKey
;
import
org.apache.shiro.subject.Subject
;
import
java.io.Serializable
;
import
java.util.Deque
;
import
java.util.LinkedList
;
public
class
SessionUntil
{
private
boolean
kickoutAfter
=
false
;
//踢出之前登录的/之后登录的用户 默认踢出之前登录的用户
private
int
maxSession
=
1
;
//同一个帐号最大会话数 默认1
private
MySessionManager
sessionManager
;
private
Cache
<
String
,
Deque
<
Serializable
>>
cache
;
public
void
setKickoutAfter
(
boolean
kickoutAfter
)
{
this
.
kickoutAfter
=
kickoutAfter
;
}
public
void
setMaxSession
(
int
maxSession
)
{
this
.
maxSession
=
maxSession
;
}
public
void
setSessionManager
(
MySessionManager
sessionManager
)
{
this
.
sessionManager
=
sessionManager
;
}
//设置Cache的key的前缀
public
void
setCacheManager
(
CacheManager
cacheManager
)
{
this
.
cache
=
cacheManager
.
getCache
(
"shiro_redis_cache"
);
}
public
void
changeSession
(
int
type
){
Subject
subject
=
SecurityUtils
.
getSubject
();
Session
session
=
subject
.
getSession
();
session
.
setTimeout
(
300000
);
Serializable
sessionId
=
session
.
getId
();
String
username
=
null
;
Deque
<
Serializable
>
deque
=
null
;
if
(
type
==
1
){
User
user
=(
User
)
subject
.
getPrincipal
();
username
=
user
.
getPhone
();
}
else
if
(
type
==
2
){
AccountInfo
account
=(
AccountInfo
)
subject
.
getPrincipal
();
username
=
account
.
getUserName
();
}
else
{
Staff
staff
=(
Staff
)
subject
.
getPrincipal
();
username
=
staff
.
getLoginName
();
}
//读取缓存,没有就存入
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
)
{
}
}
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/util/ShiroUtils.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
util
;
import
cn.wisenergy.model.app.User
;
import
org.apache.shiro.SecurityUtils
;
import
org.apache.shiro.authc.Authenticator
;
import
org.apache.shiro.authc.LogoutAware
;
import
org.apache.shiro.mgt.RealmSecurityManager
;
import
org.apache.shiro.session.Session
;
import
org.apache.shiro.subject.SimplePrincipalCollection
;
import
org.apache.shiro.subject.Subject
;
import
org.apache.shiro.subject.support.DefaultSubjectContext
;
import
org.apache.shiro.web.mgt.DefaultWebSecurityManager
;
import
org.crazycake.shiro.RedisSessionDAO
;
import
java.util.Collection
;
import
java.util.Objects
;
public
class
ShiroUtils
{
/**
* 私有构造器
**/
private
ShiroUtils
()
{
}
private
static
RedisSessionDAO
redisSessionDAO
=
SpringUtil
.
getBean
(
RedisSessionDAO
.
class
);
/**
* 获取当前用户Session
*
* @Return SysUserEntity 用户信息
*/
public
static
Session
getSession
()
{
return
SecurityUtils
.
getSubject
().
getSession
();
}
/**
* 用户登出
*/
public
static
void
logout
()
{
SecurityUtils
.
getSubject
().
logout
();
}
/**
* 获取当前用户信息
*
* @Return SysUserEntity 用户信息
*/
public
static
User
getUserInfo
()
{
User
user
=
(
User
)
SecurityUtils
.
getSubject
().
getPrincipal
();
return
user
;
}
/**
* 获取登录用户的id
*
* @return
*/
public
static
Integer
getLoginUserId
()
{
return
getUserInfo
().
getId
();
}
/**
* 获取登录用户的名称
*
* @return
*/
public
static
String
getLoginUserName
()
{
return
getUserInfo
().
getUserName
();
}
/**
* 删除用户缓存信息
*
* @Param username 用户名称
* @Param isRemoveSession 是否删除Session,删除后用户需重新登录 如果为false代表只需要重新授权即可
*/
public
static
void
deleteCache
(
String
username
,
boolean
isRemoveSession
)
{
//从缓存中获取Session
Session
session
=
null
;
// 获取当前已登录的用户session列表
Collection
<
Session
>
sessions
=
redisSessionDAO
.
getActiveSessions
();
Object
attribute
=
null
;
// 遍历Session,找到该用户名称对应的Session
for
(
Session
sessionInfo
:
sessions
)
{
attribute
=
sessionInfo
.
getAttribute
(
DefaultSubjectContext
.
PRINCIPALS_SESSION_KEY
);
if
(
attribute
==
null
)
{
continue
;
}
String
name
=
((
SimplePrincipalCollection
)
attribute
).
getPrimaryPrincipal
().
toString
();
if
(
name
==
null
)
{
continue
;
}
if
(
Objects
.
equals
(
name
,
username
))
{
session
=
sessionInfo
;
// 清除该用户以前登录时保存的session,强制退出 -> 单用户登录处理
if
(
isRemoveSession
)
{
redisSessionDAO
.
delete
(
session
);
}
}
}
if
(
session
==
null
||
attribute
==
null
)
{
return
;
}
//删除session重新登录
if
(
isRemoveSession
)
{
redisSessionDAO
.
delete
(
session
);
}
//删除Cache,再访问受限接口时会重新授权
DefaultWebSecurityManager
securityManager
=
(
DefaultWebSecurityManager
)
SecurityUtils
.
getSecurityManager
();
Authenticator
authc
=
securityManager
.
getAuthenticator
();
((
LogoutAware
)
authc
).
onLogout
((
SimplePrincipalCollection
)
attribute
);
}
/**
* 从缓存中获取指定用户名的Session
*
* @param username
*/
private
static
Session
getSessionByUsername
(
String
username
)
{
// 获取当前已登录的用户session列表
Collection
<
Session
>
sessions
=
redisSessionDAO
.
getActiveSessions
();
User
user
;
Object
attribute
;
// 遍历Session,找到该用户名称对应的Session
for
(
Session
session
:
sessions
)
{
attribute
=
session
.
getAttribute
(
DefaultSubjectContext
.
PRINCIPALS_SESSION_KEY
);
if
(
attribute
==
null
)
{
continue
;
}
user
=
(
User
)
((
SimplePrincipalCollection
)
attribute
).
getPrimaryPrincipal
();
if
(
user
==
null
)
{
continue
;
}
if
(
Objects
.
equals
(
user
.
getPhone
(),
username
))
{
return
session
;
}
}
return
null
;
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/util/SpringUtil.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
util
;
import
org.springframework.beans.BeansException
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
import
org.springframework.stereotype.Component
;
/*@Component*/
public
class
SpringUtil
implements
ApplicationContextAware
{
private
static
ApplicationContext
applicationContext
;
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
if
(
SpringUtil
.
applicationContext
==
null
)
{
SpringUtil
.
applicationContext
=
applicationContext
;
}
System
.
out
.
println
(
"========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="
+
SpringUtil
.
applicationContext
+
"========"
);
System
.
out
.
println
(
"---------------------------------------------------------------------"
);
}
//获取applicationContext
public
static
ApplicationContext
getApplicationContext
()
{
return
applicationContext
;
}
//通过name获取 Bean.
public
static
Object
getBean
(
String
name
){
return
getApplicationContext
().
getBean
(
name
);
}
//通过class获取Bean.
public
static
<
T
>
T
getBean
(
Class
<
T
>
clazz
){
return
getApplicationContext
().
getBean
(
clazz
);
}
//通过name,以及Clazz返回指定的Bean
public
static
<
T
>
T
getBean
(
String
name
,
Class
<
T
>
clazz
){
return
getApplicationContext
().
getBean
(
name
,
clazz
);
}
}
wisenergy-web-admin/src/main/java/cn/wisenergy/web/shir/util/UserModularRealmAuthenticator.java
deleted
100644 → 0
View file @
3dacc61f
package
cn
.
wisenergy
.
web
.
shir
.
util
;
import
cn.wisenergy.service.util.UserToken
;
import
com.itextpdf.text.log.Logger
;
import
com.itextpdf.text.log.LoggerFactory
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.authc.AuthenticationInfo
;
import
org.apache.shiro.authc.AuthenticationToken
;
import
org.apache.shiro.authc.pam.ModularRealmAuthenticator
;
import
org.apache.shiro.realm.Realm
;
import
java.util.ArrayList
;
import
java.util.Collection
;
public
class
UserModularRealmAuthenticator
extends
ModularRealmAuthenticator
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
UserModularRealmAuthenticator
.
class
);
@Override
protected
AuthenticationInfo
doAuthenticate
(
AuthenticationToken
authenticationToken
)
throws
AuthenticationException
{
logger
.
info
(
"UserModularRealmAuthenticator:method doAuthenticate() execute "
);
// 判断getRealms()是否返回为空
assertRealmsConfigured
();
// 强制转换回自定义的CustomizedToken
UserToken
userToken
=
(
UserToken
)
authenticationToken
;
// 登录类型
String
loginType
=
userToken
.
getLoginType
();
// 所有Realm
Collection
<
Realm
>
realms
=
getRealms
();
// 登录类型对应的所有Realm
Collection
<
Realm
>
typeRealms
=
new
ArrayList
<>();
for
(
Realm
realm
:
realms
)
{
if
(
realm
.
getName
().
contains
(
loginType
));
typeRealms
.
add
(
realm
);
}
// 判断是单Realm还是多Realm
if
(
typeRealms
.
size
()
==
1
){
logger
.
info
(
"doSingleRealmAuthentication() execute "
);
return
doSingleRealmAuthentication
(((
ArrayList
<
Realm
>)
typeRealms
).
get
(
0
),
userToken
);
}
else
{
logger
.
info
(
"doMultiRealmAuthentication() execute "
);
return
doMultiRealmAuthentication
(
typeRealms
,
userToken
);
}
}
}
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