Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Eladmin
Commits
563f3657
Commit
563f3657
authored
May 26, 2022
by
Zheng Jie
Browse files
Merge branch 'master' into deploy
parents
290ed67e
78b7d21d
Changes
16
Show whitespace changes
Inline
Side-by-side
eladmin-system/src/main/java/me/zhengjie/modules/security/config/SpringSecurityConfig.java
View file @
563f3657
...
@@ -20,7 +20,7 @@ import me.zhengjie.annotation.AnonymousAccess;
...
@@ -20,7 +20,7 @@ import me.zhengjie.annotation.AnonymousAccess;
import
me.zhengjie.modules.security.config.bean.SecurityProperties
;
import
me.zhengjie.modules.security.config.bean.SecurityProperties
;
import
me.zhengjie.modules.security.security.*
;
import
me.zhengjie.modules.security.security.*
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.modules.security.service.UserCache
Clean
;
import
me.zhengjie.modules.security.service.UserCache
Manager
;
import
me.zhengjie.utils.enums.RequestMethodEnum
;
import
me.zhengjie.utils.enums.RequestMethodEnum
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
...
@@ -58,7 +58,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
...
@@ -58,7 +58,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
private
final
ApplicationContext
applicationContext
;
private
final
ApplicationContext
applicationContext
;
private
final
SecurityProperties
properties
;
private
final
SecurityProperties
properties
;
private
final
OnlineUserService
onlineUserService
;
private
final
OnlineUserService
onlineUserService
;
private
final
UserCache
Clean
userCache
Clean
;
private
final
UserCache
Manager
userCache
Manager
;
@Bean
@Bean
GrantedAuthorityDefaults
grantedAuthorityDefaults
()
{
GrantedAuthorityDefaults
grantedAuthorityDefaults
()
{
...
@@ -138,7 +138,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
...
@@ -138,7 +138,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
}
}
private
TokenConfigurer
securityConfigurerAdapter
()
{
private
TokenConfigurer
securityConfigurerAdapter
()
{
return
new
TokenConfigurer
(
tokenProvider
,
properties
,
onlineUserService
,
userCache
Clean
);
return
new
TokenConfigurer
(
tokenProvider
,
properties
,
onlineUserService
,
userCache
Manager
);
}
}
private
Map
<
String
,
Set
<
String
>>
getAnonymousUrl
(
Map
<
RequestMappingInfo
,
HandlerMethod
>
handlerMethodMap
)
{
private
Map
<
String
,
Set
<
String
>>
getAnonymousUrl
(
Map
<
RequestMappingInfo
,
HandlerMethod
>
handlerMethodMap
)
{
...
...
eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java
View file @
563f3657
...
@@ -20,7 +20,6 @@ import com.wf.captcha.base.Captcha;
...
@@ -20,7 +20,6 @@ import com.wf.captcha.base.Captcha;
import
lombok.Data
;
import
lombok.Data
;
import
me.zhengjie.exception.BadConfigurationException
;
import
me.zhengjie.exception.BadConfigurationException
;
import
me.zhengjie.utils.StringUtils
;
import
me.zhengjie.utils.StringUtils
;
import
java.awt.*
;
import
java.awt.*
;
import
java.util.Objects
;
import
java.util.Objects
;
...
@@ -40,19 +39,12 @@ public class LoginProperties {
...
@@ -40,19 +39,12 @@ public class LoginProperties {
private
LoginCode
loginCode
;
private
LoginCode
loginCode
;
/**
public
static
final
String
cacheKey
=
"USER-LOGIN-DATA"
;
* 用户登录信息缓存
*/
private
boolean
cacheEnable
;
public
boolean
isSingleLogin
()
{
public
boolean
isSingleLogin
()
{
return
singleLogin
;
return
singleLogin
;
}
}
public
boolean
isCacheEnable
()
{
return
cacheEnable
;
}
/**
/**
* 获取验证码生产类
* 获取验证码生产类
*
*
...
...
eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenConfigurer.java
View file @
563f3657
...
@@ -18,7 +18,7 @@ package me.zhengjie.modules.security.security;
...
@@ -18,7 +18,7 @@ package me.zhengjie.modules.security.security;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
me.zhengjie.modules.security.config.bean.SecurityProperties
;
import
me.zhengjie.modules.security.config.bean.SecurityProperties
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.modules.security.service.UserCache
Clean
;
import
me.zhengjie.modules.security.service.UserCache
Manager
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.web.DefaultSecurityFilterChain
;
import
org.springframework.security.web.DefaultSecurityFilterChain
;
...
@@ -33,11 +33,11 @@ public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFi
...
@@ -33,11 +33,11 @@ public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFi
private
final
TokenProvider
tokenProvider
;
private
final
TokenProvider
tokenProvider
;
private
final
SecurityProperties
properties
;
private
final
SecurityProperties
properties
;
private
final
OnlineUserService
onlineUserService
;
private
final
OnlineUserService
onlineUserService
;
private
final
UserCache
Clean
userCache
Clean
;
private
final
UserCache
Manager
userCache
Manager
;
@Override
@Override
public
void
configure
(
HttpSecurity
http
)
{
public
void
configure
(
HttpSecurity
http
)
{
TokenFilter
customFilter
=
new
TokenFilter
(
tokenProvider
,
properties
,
onlineUserService
,
userCache
Clean
);
TokenFilter
customFilter
=
new
TokenFilter
(
tokenProvider
,
properties
,
onlineUserService
,
userCache
Manager
);
http
.
addFilterBefore
(
customFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
http
.
addFilterBefore
(
customFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
}
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java
View file @
563f3657
...
@@ -18,7 +18,7 @@ package me.zhengjie.modules.security.security;
...
@@ -18,7 +18,7 @@ package me.zhengjie.modules.security.security;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.core.util.StrUtil
;
import
io.jsonwebtoken.ExpiredJwtException
;
import
io.jsonwebtoken.ExpiredJwtException
;
import
me.zhengjie.modules.security.config.bean.SecurityProperties
;
import
me.zhengjie.modules.security.config.bean.SecurityProperties
;
import
me.zhengjie.modules.security.service.UserCache
Clean
;
import
me.zhengjie.modules.security.service.UserCache
Manager
;
import
me.zhengjie.modules.security.service.dto.OnlineUserDto
;
import
me.zhengjie.modules.security.service.dto.OnlineUserDto
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
...
@@ -27,7 +27,6 @@ import org.springframework.security.core.Authentication;
...
@@ -27,7 +27,6 @@ import org.springframework.security.core.Authentication;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.util.StringUtils
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.filter.GenericFilterBean
;
import
org.springframework.web.filter.GenericFilterBean
;
import
javax.servlet.FilterChain
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletRequest
;
...
@@ -46,19 +45,19 @@ public class TokenFilter extends GenericFilterBean {
...
@@ -46,19 +45,19 @@ public class TokenFilter extends GenericFilterBean {
private
final
TokenProvider
tokenProvider
;
private
final
TokenProvider
tokenProvider
;
private
final
SecurityProperties
properties
;
private
final
SecurityProperties
properties
;
private
final
OnlineUserService
onlineUserService
;
private
final
OnlineUserService
onlineUserService
;
private
final
UserCache
Clean
userCache
Clean
;
private
final
UserCache
Manager
userCache
Manager
;
/**
/**
* @param tokenProvider Token
* @param tokenProvider Token
* @param properties JWT
* @param properties JWT
* @param onlineUserService 用户在线
* @param onlineUserService 用户在线
* @param userCache
Clean
用户缓存
清理
工具
* @param userCache
Manager
用户缓存工具
*/
*/
public
TokenFilter
(
TokenProvider
tokenProvider
,
SecurityProperties
properties
,
OnlineUserService
onlineUserService
,
UserCache
Clean
userCache
Clean
)
{
public
TokenFilter
(
TokenProvider
tokenProvider
,
SecurityProperties
properties
,
OnlineUserService
onlineUserService
,
UserCache
Manager
userCache
Manager
)
{
this
.
properties
=
properties
;
this
.
properties
=
properties
;
this
.
onlineUserService
=
onlineUserService
;
this
.
onlineUserService
=
onlineUserService
;
this
.
tokenProvider
=
tokenProvider
;
this
.
tokenProvider
=
tokenProvider
;
this
.
userCache
Clean
=
userCache
Clean
;
this
.
userCache
Manager
=
userCache
Manager
;
}
}
@Override
@Override
...
@@ -77,7 +76,7 @@ public class TokenFilter extends GenericFilterBean {
...
@@ -77,7 +76,7 @@ public class TokenFilter extends GenericFilterBean {
cleanUserCache
=
true
;
cleanUserCache
=
true
;
}
finally
{
}
finally
{
if
(
cleanUserCache
||
Objects
.
isNull
(
onlineUserDto
))
{
if
(
cleanUserCache
||
Objects
.
isNull
(
onlineUserDto
))
{
userCache
Clean
.
cleanUserCache
(
String
.
valueOf
(
tokenProvider
.
getClaims
(
token
).
get
(
TokenProvider
.
AUTHORITIES_KEY
)));
userCache
Manager
.
cleanUserCache
(
String
.
valueOf
(
tokenProvider
.
getClaims
(
token
).
get
(
TokenProvider
.
AUTHORITIES_KEY
)));
}
}
}
}
if
(
onlineUserDto
!=
null
&&
StringUtils
.
hasText
(
token
))
{
if
(
onlineUserDto
!=
null
&&
StringUtils
.
hasText
(
token
))
{
...
...
eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java
deleted
100644 → 0
View file @
290ed67e
/*
* Copyright 2019-2020 the original author or authors.
*
* 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
me.zhengjie.modules.security.service
;
import
lombok.AllArgsConstructor
;
import
me.zhengjie.utils.StringUtils
;
import
org.springframework.stereotype.Component
;
/**
* @author: liaojinlong
* @date: 2020/6/11 18:01
* @apiNote: 用于清理 用户登录信息缓存,为防止Spring循环依赖与安全考虑 ,单独构成工具类
*/
@Component
@AllArgsConstructor
public
class
UserCacheClean
{
private
final
UserCacheManager
userCacheManager
;
/**
* 清理特定用户缓存信息<br>
* 用户信息变更时
*
* @param userName /
*/
public
void
cleanUserCache
(
String
userName
)
{
if
(
StringUtils
.
isNotEmpty
(
userName
))
{
userCacheManager
.
remove
(
userName
);
}
}
/**
* 清理所有用户的缓存信息<br>
* ,如发生角色授权信息变化,可以简便的全部失效缓存
*/
public
void
cleanAll
()
{
userCacheManager
.
clear
();
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheManager.java
View file @
563f3657
/*
* Copyright 2019-2020 Zheng Jie
*
* 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
me.zhengjie.modules.security.service
;
package
me.zhengjie.modules.security.service
;
import
lombok.extern.slf4j.Slf4j
;
import
cn.hutool.core.util.RandomUtil
;
import
me.zhengjie.modules.security.config.bean.LoginProperties
;
import
me.zhengjie.modules.security.service.dto.JwtUserDto
;
import
me.zhengjie.modules.security.service.dto.JwtUserDto
;
import
me.zhengjie.utils.RedisUtils
;
import
me.zhengjie.utils.StringUtils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.util.Iterator
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.atomic.AtomicBoolean
;
/**
/**
* 用户缓存
* @author Zheng Jie
*
* @description 用户缓存管理
* @author TikiWong
* @date 2022-05-26
* @date 2022/1/27 8:23
**/
**/
@Slf4j
@Component
@Component
public
class
UserCacheManager
{
public
class
UserCacheManager
{
@Value
(
"${user-cache.min-evictable-size}"
)
@Resource
private
int
minEvictableSize
;
private
RedisUtils
redisUtils
;
@Value
(
"${user-cache.min-evictable-interval}"
)
@Value
(
"${login.user-cache.idle-time}"
)
private
long
minEvictableInterval
;
private
long
idleTime
;
@Value
(
"${user-cache.min-idle-time}"
)
private
long
minIdleTime
;
private
final
Map
<
String
,
Node
>
cache
=
new
ConcurrentHashMap
<>();
private
final
AtomicBoolean
expelLock
=
new
AtomicBoolean
(
true
);
private
long
nextMinEvictableTime
=
0
;
public
Future
<
JwtUserDto
>
putIfAbsent
(
String
username
,
Future
<
JwtUserDto
>
ft
)
{
Node
tryNode
=
new
Node
(
ft
);
Node
node
=
cache
.
putIfAbsent
(
username
,
tryNode
);
expel
();
return
nodeToDate
(
node
);
}
/**
/**
* 缓存
回收
*
返回用户
缓存
*
为避免超过边界后回收热点数据设置了最小生存时间
*
@param userName 用户名
*
回收时会保留在最小生存时间内的数据
*
@return JwtUserDto
*
*/
*/
public
void
expel
(
)
{
public
JwtUserDto
getUserCache
(
String
userName
)
{
long
now
=
System
.
currentTimeMillis
();
if
(
StringUtils
.
isNotEmpty
(
userName
))
{
if
(
cache
.
size
()
<
minEvictableSize
||
// 获取数据
now
<
nextMinEvictableTime
||
Object
obj
=
redisUtils
.
hget
(
LoginProperties
.
cacheKey
,
userName
);
!
expelLock
.
compareAndSet
(
true
,
false
))
{
if
(
obj
!=
null
)
{
return
;
return
(
JwtUserDto
)
obj
;
}
}
long
oldestTime
=
now
;
int
evictedCount
=
0
;
try
{
Iterator
<
Map
.
Entry
<
String
,
Node
>>
iterator
=
cache
.
entrySet
().
iterator
();
while
(
iterator
.
hasNext
())
{
Map
.
Entry
<
String
,
Node
>
entry
=
iterator
.
next
();
long
nodeTime
=
entry
.
getValue
().
getTime
();
if
(
nodeTime
+
minIdleTime
<
now
)
{
iterator
.
remove
();
evictedCount
++;
}
oldestTime
=
Math
.
min
(
oldestTime
,
nodeTime
);
}
}
finally
{
this
.
nextMinEvictableTime
=
Math
.
max
(
now
+
minEvictableInterval
,
oldestTime
);
expelLock
.
set
(
true
);
log
.
info
(
"回收掉【{}】条用户缓存, 剩余缓存数为【{}】,下次可回收时间为【{}】秒后"
,
evictedCount
,
cache
.
size
(),
(
this
.
nextMinEvictableTime
-
now
)
/
1000
);
}
}
return
null
;
}
}
public
Future
<
JwtUserDto
>
get
(
String
username
)
{
/**
return
nodeToDate
(
cache
.
get
(
username
));
* 添加缓存到Redis
}
* @param userName 用户名
*/
public
void
clear
()
{
@Async
cache
.
clear
();
public
void
addUserCache
(
String
userName
,
JwtUserDto
user
)
{
}
if
(
StringUtils
.
isNotEmpty
(
userName
))
{
// 添加数据, 避免数据同时过期
public
void
remove
(
String
username
)
{
long
time
=
idleTime
+
RandomUtil
.
randomInt
(
900
,
1800
);
cache
.
remove
(
username
);
redisUtils
.
hset
(
LoginProperties
.
cacheKey
,
userName
,
user
,
time
);
}
private
Future
<
JwtUserDto
>
nodeToDate
(
Node
node
)
{
return
node
==
null
?
null
:
node
.
getData
();
}
private
static
class
Node
{
private
final
Future
<
JwtUserDto
>
data
;
private
final
long
time
;
public
Node
(
Future
<
JwtUserDto
>
data
)
{
this
.
data
=
data
;
this
.
time
=
System
.
currentTimeMillis
();
}
}
public
Future
<
JwtUserDto
>
getData
()
{
return
data
;
}
}
public
long
getTime
()
{
/**
return
time
;
* 清理用户缓存信息
* 用户信息变更时
* @param userName 用户名
*/
@Async
public
void
cleanUserCache
(
String
userName
)
{
if
(
StringUtils
.
isNotEmpty
(
userName
))
{
// 清除数据
redisUtils
.
hdel
(
LoginProperties
.
cacheKey
,
userName
);
}
}
}
}
}
}
\ No newline at end of file
eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java
View file @
563f3657
...
@@ -16,50 +16,38 @@
...
@@ -16,50 +16,38 @@
package
me.zhengjie.modules.security.service
;
package
me.zhengjie.modules.security.service
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.exception.EntityNotFoundException
;
import
me.zhengjie.exception.EntityNotFoundException
;
import
me.zhengjie.modules.security.config.bean.LoginProperties
;
import
me.zhengjie.modules.security.service.dto.JwtUserDto
;
import
me.zhengjie.modules.security.service.dto.JwtUserDto
;
import
me.zhengjie.modules.system.service.DataService
;
import
me.zhengjie.modules.system.service.DataService
;
import
me.zhengjie.modules.system.service.RoleService
;
import
me.zhengjie.modules.system.service.RoleService
;
import
me.zhengjie.modules.system.service.UserService
;
import
me.zhengjie.modules.system.service.UserService
;
import
me.zhengjie.modules.system.service.dto.UserDto
;
import
me.zhengjie.modules.system.service.dto.User
Login
Dto
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
java.util.List
;
import
java.util.concurrent.*
;
import
java.util.concurrent.atomic.AtomicInteger
;
/**
/**
* @author Zheng Jie
* @author Zheng Jie
* @date 2018-11-22
* @date 2018-11-22
*/
*/
@Slf4j
@RequiredArgsConstructor
@RequiredArgsConstructor
@Service
(
"userDetailsService"
)
@Service
(
"userDetailsService"
)
public
class
UserDetailsServiceImpl
implements
UserDetailsService
{
public
class
UserDetailsServiceImpl
implements
UserDetailsService
{
private
final
UserService
userService
;
private
final
UserService
userService
;
private
final
RoleService
roleService
;
private
final
RoleService
roleService
;
private
final
DataService
dataService
;
private
final
DataService
dataService
;
private
final
LoginProperties
loginProperties
;
private
final
UserCacheManager
userCacheManager
;
private
final
UserCacheManager
USER_DTO_CACHE
;
public
void
setEnableCache
(
boolean
enableCache
)
{
this
.
loginProperties
.
setCacheEnable
(
enableCache
);
}
public
static
ExecutorService
executor
=
newThreadPool
();
@Override
@Override
public
JwtUserDto
loadUserByUsername
(
String
username
)
{
public
JwtUserDto
loadUserByUsername
(
String
username
)
{
JwtUserDto
jwtUserDto
=
null
;
JwtUserDto
jwtUserDto
=
userCacheManager
.
getUserCache
(
username
);
Future
<
JwtUserDto
>
future
=
USER_DTO_CACHE
.
get
(
username
);
if
(
jwtUserDto
==
null
){
if
(!
loginProperties
.
isCacheEnable
())
{
UserLoginDto
user
;
UserDto
user
;
try
{
try
{
user
=
userService
.
findByName
(
username
);
user
=
userService
.
getLoginData
(
username
);
}
catch
(
EntityNotFoundException
e
)
{
}
catch
(
EntityNotFoundException
e
)
{
// SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException
// SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException
throw
new
UsernameNotFoundException
(
username
,
e
);
throw
new
UsernameNotFoundException
(
username
,
e
);
...
@@ -75,85 +63,10 @@ public class UserDetailsServiceImpl implements UserDetailsService {
...
@@ -75,85 +63,10 @@ public class UserDetailsServiceImpl implements UserDetailsService {
dataService
.
getDeptIds
(
user
),
dataService
.
getDeptIds
(
user
),
roleService
.
mapToGrantedAuthorities
(
user
)
roleService
.
mapToGrantedAuthorities
(
user
)
);
);
// 添加缓存数据
userCacheManager
.
addUserCache
(
username
,
jwtUserDto
);
}
}
return
jwtUserDto
;
}
if
(
future
==
null
)
{
Callable
<
JwtUserDto
>
call
=
()
->
getJwtBySearchDb
(
username
);
FutureTask
<
JwtUserDto
>
ft
=
new
FutureTask
<>(
call
);
future
=
USER_DTO_CACHE
.
putIfAbsent
(
username
,
ft
);
if
(
future
==
null
)
{
future
=
ft
;
executor
.
submit
(
ft
);
}
try
{
return
future
.
get
();
}
catch
(
CancellationException
e
)
{
USER_DTO_CACHE
.
remove
(
username
);
System
.
out
.
println
(
"error"
+
Thread
.
currentThread
().
getName
());
}
catch
(
InterruptedException
|
ExecutionException
e
)
{
throw
new
RuntimeException
(
e
.
getMessage
());
}
}
else
{
try
{
jwtUserDto
=
future
.
get
();
}
catch
(
InterruptedException
|
ExecutionException
e
)
{
throw
new
RuntimeException
(
e
.
getMessage
());
}
// 检查dataScope是否修改
List
<
Long
>
dataScopes
=
jwtUserDto
.
getDataScopes
();
dataScopes
.
clear
();
dataScopes
.
addAll
(
dataService
.
getDeptIds
(
jwtUserDto
.
getUser
()));
}
}
return
jwtUserDto
;
return
jwtUserDto
;
}
private
JwtUserDto
getJwtBySearchDb
(
String
username
)
{
UserDto
user
;
try
{
user
=
userService
.
findByName
(
username
);
}
catch
(
EntityNotFoundException
e
)
{
// SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException
throw
new
UsernameNotFoundException
(
""
,
e
);
}
if
(
user
==
null
)
{
throw
new
UsernameNotFoundException
(
""
);
}
else
{
if
(!
user
.
getEnabled
())
{
throw
new
BadRequestException
(
"账号未激活!"
);
}
return
new
JwtUserDto
(
user
,
dataService
.
getDeptIds
(
user
),
roleService
.
mapToGrantedAuthorities
(
user
)
);
}
}
public
static
ExecutorService
newThreadPool
()
{
ThreadFactory
namedThreadFactory
=
new
ThreadFactory
()
{
final
AtomicInteger
sequence
=
new
AtomicInteger
(
1
);
@Override
public
Thread
newThread
(
Runnable
r
)
{
Thread
thread
=
new
Thread
(
r
);
int
seq
=
this
.
sequence
.
getAndIncrement
();
thread
.
setName
(
"future-task-thread"
+
(
seq
>
1
?
"-"
+
seq
:
""
));
if
(!
thread
.
isDaemon
())
{
thread
.
setDaemon
(
true
);
}
return
thread
;
}
};
return
new
ThreadPoolExecutor
(
10
,
200
,
0L
,
TimeUnit
.
MILLISECONDS
,
new
LinkedBlockingQueue
<>(
1024
),
namedThreadFactory
,
new
ThreadPoolExecutor
.
AbortPolicy
());
}
}
}
}
eladmin-system/src/main/java/me/zhengjie/modules/security/service/dto/JwtUserDto.java
View file @
563f3657
...
@@ -18,8 +18,7 @@ package me.zhengjie.modules.security.service.dto;
...
@@ -18,8 +18,7 @@ package me.zhengjie.modules.security.service.dto;
import
com.alibaba.fastjson.annotation.JSONField
;
import
com.alibaba.fastjson.annotation.JSONField
;
import
lombok.AllArgsConstructor
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
lombok.Getter
;
import
me.zhengjie.modules.system.service.dto.UserDto
;
import
me.zhengjie.modules.system.service.dto.UserLoginDto
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.Set
;
...
@@ -33,11 +32,10 @@ import java.util.stream.Collectors;
...
@@ -33,11 +32,10 @@ import java.util.stream.Collectors;
@AllArgsConstructor
@AllArgsConstructor
public
class
JwtUserDto
implements
UserDetails
{
public
class
JwtUserDto
implements
UserDetails
{
private
final
UserDto
user
;
private
final
User
Login
Dto
user
;
private
final
List
<
Long
>
dataScopes
;
private
final
List
<
Long
>
dataScopes
;
@JSONField
(
serialize
=
false
)
private
final
List
<
AuthorityDto
>
authorities
;
private
final
List
<
AuthorityDto
>
authorities
;
public
Set
<
String
>
getRoles
()
{
public
Set
<
String
>
getRoles
()
{
...
...
eladmin-system/src/main/java/me/zhengjie/modules/system/service/UserService.java
View file @
563f3657
...
@@ -17,6 +17,7 @@ package me.zhengjie.modules.system.service;
...
@@ -17,6 +17,7 @@ package me.zhengjie.modules.system.service;
import
me.zhengjie.modules.system.domain.User
;
import
me.zhengjie.modules.system.domain.User
;
import
me.zhengjie.modules.system.service.dto.UserDto
;
import
me.zhengjie.modules.system.service.dto.UserDto
;
import
me.zhengjie.modules.system.service.dto.UserLoginDto
;
import
me.zhengjie.modules.system.service.dto.UserQueryCriteria
;
import
me.zhengjie.modules.system.service.dto.UserQueryCriteria
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.web.multipart.MultipartFile
;
import
org.springframework.web.multipart.MultipartFile
;
...
@@ -65,6 +66,13 @@ public interface UserService {
...
@@ -65,6 +66,13 @@ public interface UserService {
*/
*/
UserDto
findByName
(
String
userName
);
UserDto
findByName
(
String
userName
);
/**
* 根据用户名查询
* @param userName /
* @return /
*/
UserLoginDto
getLoginData
(
String
userName
);
/**
/**
* 修改密码
* 修改密码
* @param username 用户名
* @param username 用户名
...
...
eladmin-system/src/main/java/me/zhengjie/modules/system/service/dto/UserLoginDto.java
0 → 100644
View file @
563f3657
/*
* Copyright 2019-2020 Zheng Jie
*
* 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
me.zhengjie.modules.system.service.dto
;
/**
* @author Zheng Jie
* @description 用户缓存时使用
* @date 2022-05-26
**/
public
class
UserLoginDto
extends
UserDto
{
private
String
password
;
private
Boolean
isAdmin
;
}
eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java
View file @
563f3657
...
@@ -18,7 +18,7 @@ package me.zhengjie.modules.system.service.impl;
...
@@ -18,7 +18,7 @@ package me.zhengjie.modules.system.service.impl;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.collection.CollectionUtil
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.modules.security.service.UserCache
Clean
;
import
me.zhengjie.modules.security.service.UserCache
Manager
;
import
me.zhengjie.modules.security.service.dto.AuthorityDto
;
import
me.zhengjie.modules.security.service.dto.AuthorityDto
;
import
me.zhengjie.modules.system.domain.Menu
;
import
me.zhengjie.modules.system.domain.Menu
;
import
me.zhengjie.modules.system.domain.Role
;
import
me.zhengjie.modules.system.domain.Role
;
...
@@ -60,7 +60,7 @@ public class RoleServiceImpl implements RoleService {
...
@@ -60,7 +60,7 @@ public class RoleServiceImpl implements RoleService {
private
final
RoleSmallMapper
roleSmallMapper
;
private
final
RoleSmallMapper
roleSmallMapper
;
private
final
RedisUtils
redisUtils
;
private
final
RedisUtils
redisUtils
;
private
final
UserRepository
userRepository
;
private
final
UserRepository
userRepository
;
private
final
UserCache
Clean
userCache
Clean
;
private
final
UserCache
Manager
userCache
Manager
;
@Override
@Override
public
List
<
RoleDto
>
queryAll
()
{
public
List
<
RoleDto
>
queryAll
()
{
...
@@ -213,7 +213,7 @@ public class RoleServiceImpl implements RoleService {
...
@@ -213,7 +213,7 @@ public class RoleServiceImpl implements RoleService {
public
void
delCaches
(
Long
id
,
List
<
User
>
users
)
{
public
void
delCaches
(
Long
id
,
List
<
User
>
users
)
{
users
=
CollectionUtil
.
isEmpty
(
users
)
?
userRepository
.
findByRoleId
(
id
)
:
users
;
users
=
CollectionUtil
.
isEmpty
(
users
)
?
userRepository
.
findByRoleId
(
id
)
:
users
;
if
(
CollectionUtil
.
isNotEmpty
(
users
))
{
if
(
CollectionUtil
.
isNotEmpty
(
users
))
{
users
.
forEach
(
item
->
userCache
Clean
.
cleanUserCache
(
item
.
getUsername
()));
users
.
forEach
(
item
->
userCache
Manager
.
cleanUserCache
(
item
.
getUsername
()));
Set
<
Long
>
userIds
=
users
.
stream
().
map
(
User:
:
getId
).
collect
(
Collectors
.
toSet
());
Set
<
Long
>
userIds
=
users
.
stream
().
map
(
User:
:
getId
).
collect
(
Collectors
.
toSet
());
redisUtils
.
delByKeys
(
CacheKey
.
DATA_USER
,
userIds
);
redisUtils
.
delByKeys
(
CacheKey
.
DATA_USER
,
userIds
);
redisUtils
.
delByKeys
(
CacheKey
.
MENU_USER
,
userIds
);
redisUtils
.
delByKeys
(
CacheKey
.
MENU_USER
,
userIds
);
...
...
eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java
View file @
563f3657
...
@@ -19,16 +19,14 @@ import lombok.RequiredArgsConstructor;
...
@@ -19,16 +19,14 @@ import lombok.RequiredArgsConstructor;
import
me.zhengjie.config.FileProperties
;
import
me.zhengjie.config.FileProperties
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.exception.BadRequestException
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.modules.security.service.OnlineUserService
;
import
me.zhengjie.modules.security.service.UserCache
Clean
;
import
me.zhengjie.modules.security.service.UserCache
Manager
;
import
me.zhengjie.modules.system.domain.User
;
import
me.zhengjie.modules.system.domain.User
;
import
me.zhengjie.exception.EntityExistException
;
import
me.zhengjie.exception.EntityExistException
;
import
me.zhengjie.exception.EntityNotFoundException
;
import
me.zhengjie.exception.EntityNotFoundException
;
import
me.zhengjie.modules.system.repository.UserRepository
;
import
me.zhengjie.modules.system.repository.UserRepository
;
import
me.zhengjie.modules.system.service.UserService
;
import
me.zhengjie.modules.system.service.UserService
;
import
me.zhengjie.modules.system.service.dto.JobSmallDto
;
import
me.zhengjie.modules.system.service.dto.*
;
import
me.zhengjie.modules.system.service.dto.RoleSmallDto
;
import
me.zhengjie.modules.system.service.mapstruct.UserLoginMapper
;
import
me.zhengjie.modules.system.service.dto.UserDto
;
import
me.zhengjie.modules.system.service.dto.UserQueryCriteria
;
import
me.zhengjie.modules.system.service.mapstruct.UserMapper
;
import
me.zhengjie.modules.system.service.mapstruct.UserMapper
;
import
me.zhengjie.utils.*
;
import
me.zhengjie.utils.*
;
import
org.springframework.cache.annotation.CacheConfig
;
import
org.springframework.cache.annotation.CacheConfig
;
...
@@ -58,8 +56,9 @@ public class UserServiceImpl implements UserService {
...
@@ -58,8 +56,9 @@ public class UserServiceImpl implements UserService {
private
final
UserMapper
userMapper
;
private
final
UserMapper
userMapper
;
private
final
FileProperties
properties
;
private
final
FileProperties
properties
;
private
final
RedisUtils
redisUtils
;
private
final
RedisUtils
redisUtils
;
private
final
UserCache
Clean
userCache
Clean
;
private
final
UserCache
Manager
userCache
Manager
;
private
final
OnlineUserService
onlineUserService
;
private
final
OnlineUserService
onlineUserService
;
private
final
UserLoginMapper
userLoginMapper
;
@Override
@Override
public
Object
queryAll
(
UserQueryCriteria
criteria
,
Pageable
pageable
)
{
public
Object
queryAll
(
UserQueryCriteria
criteria
,
Pageable
pageable
)
{
...
@@ -175,6 +174,16 @@ public class UserServiceImpl implements UserService {
...
@@ -175,6 +174,16 @@ public class UserServiceImpl implements UserService {
}
}
}
}
@Override
public
UserLoginDto
getLoginData
(
String
userName
)
{
User
user
=
userRepository
.
findByUsername
(
userName
);
if
(
user
==
null
)
{
throw
new
EntityNotFoundException
(
User
.
class
,
"name"
,
userName
);
}
else
{
return
userLoginMapper
.
toDto
(
user
);
}
}
@Override
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
void
updatePass
(
String
username
,
String
pass
)
{
public
void
updatePass
(
String
username
,
String
pass
)
{
...
@@ -252,6 +261,6 @@ public class UserServiceImpl implements UserService {
...
@@ -252,6 +261,6 @@ public class UserServiceImpl implements UserService {
* @param username /
* @param username /
*/
*/
private
void
flushCache
(
String
username
)
{
private
void
flushCache
(
String
username
)
{
userCache
Clean
.
cleanUserCache
(
username
);
userCache
Manager
.
cleanUserCache
(
username
);
}
}
}
}
eladmin-system/src/main/java/me/zhengjie/modules/system/service/mapstruct/UserLoginMapper.java
0 → 100644
View file @
563f3657
/*
* Copyright 2019-2020 Zheng Jie
*
* 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
me.zhengjie.modules.system.service.mapstruct
;
import
me.zhengjie.base.BaseMapper
;
import
me.zhengjie.modules.system.domain.User
;
import
me.zhengjie.modules.system.service.dto.UserLoginDto
;
import
org.mapstruct.Mapper
;
import
org.mapstruct.ReportingPolicy
;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Mapper
(
componentModel
=
"spring"
,
uses
=
{
RoleMapper
.
class
,
DeptMapper
.
class
,
JobMapper
.
class
},
unmappedTargetPolicy
=
ReportingPolicy
.
IGNORE
)
public
interface
UserLoginMapper
extends
BaseMapper
<
UserLoginDto
,
User
>
{
}
eladmin-system/src/main/resources/config/application-dev.yml
View file @
563f3657
...
@@ -51,10 +51,12 @@ spring:
...
@@ -51,10 +51,12 @@ spring:
# 登录相关配置
# 登录相关配置
login
:
login
:
# 登录缓存
cache-enable
:
true
# 是否限制单用户登录
# 是否限制单用户登录
single-login
:
false
single-login
:
false
# Redis用户登录缓存配置
user-cache
:
# 存活时间/秒
idle-time
:
7200
# 验证码
# 验证码
login-code
:
login-code
:
# 验证码类型配置 查看 LoginProperties 类
# 验证码类型配置 查看 LoginProperties 类
...
...
eladmin-system/src/main/resources/config/application-prod.yml
View file @
563f3657
...
@@ -52,10 +52,12 @@ spring:
...
@@ -52,10 +52,12 @@ spring:
# 登录相关配置
# 登录相关配置
login
:
login
:
# 登录缓存
cache-enable
:
true
# 是否限制单用户登录
# 是否限制单用户登录
single-login
:
false
single-login
:
false
# Redis用户登录缓存配置
user-cache
:
# 存活时间/秒
idle-time
:
7200
# 验证码
# 验证码
login-code
:
login-code
:
# 验证码类型配置 查看 LoginProperties 类
# 验证码类型配置 查看 LoginProperties 类
...
...
eladmin-system/src/main/resources/config/application.yml
View file @
563f3657
...
@@ -58,12 +58,3 @@ code:
...
@@ -58,12 +58,3 @@ code:
#密码加密传输,前端公钥加密,后端私钥解密
#密码加密传输,前端公钥加密,后端私钥解密
rsa
:
rsa
:
private_key
:
MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
private_key
:
MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
# 内存用户缓存配置
user-cache
:
# 最小回收数(当缓存数量达到此值时进行回收)
min-evictable-size
:
512
# 最小回收间隔
min-evictable-interval
:
1800000
# 最小存活时间 (ms)
min-idle-time
:
3600000
\ No newline at end of file
Write
Preview
Supports
Markdown
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