Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
finance-manage
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
finance-oa
finance-manage
Commits
aee5d417
Commit
aee5d417
authored
Jul 30, 2022
by
RuoYi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
支持配置密码最大错误次数/锁定时间
parent
250c5ba2
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
184 additions
and
3 deletions
+184
-3
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java
...ava/com/ruoyi/web/controller/monitor/CacheController.java
+1
-0
ruoyi-admin/src/main/resources/application.yml
ruoyi-admin/src/main/resources/application.yml
+8
-0
ruoyi-admin/src/main/resources/i18n/messages.properties
ruoyi-admin/src/main/resources/i18n/messages.properties
+1
-1
ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
...c/main/java/com/ruoyi/common/constant/CacheConstants.java
+5
-0
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
...src/main/java/com/ruoyi/common/core/redis/RedisCache.java
+22
-0
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java
...exception/user/UserPasswordRetryLimitExceedException.java
+16
-0
ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/AuthenticationContextHolder.java
...amework/security/context/AuthenticationContextHolder.java
+28
-0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
...java/com/ruoyi/framework/web/service/SysLoginService.java
+4
-2
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java
...a/com/ruoyi/framework/web/service/SysPasswordService.java
+94
-0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
...m/ruoyi/framework/web/service/UserDetailsServiceImpl.java
+5
-0
No files found.
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java
View file @
aee5d417
...
@@ -41,6 +41,7 @@ public class CacheController
...
@@ -41,6 +41,7 @@ public class CacheController
caches
.
add
(
new
SysCache
(
CacheConstants
.
CAPTCHA_CODE_KEY
,
"验证码"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
CAPTCHA_CODE_KEY
,
"验证码"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
REPEAT_SUBMIT_KEY
,
"防重提交"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
REPEAT_SUBMIT_KEY
,
"防重提交"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
RATE_LIMIT_KEY
,
"限流处理"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
RATE_LIMIT_KEY
,
"限流处理"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
PWD_ERR_CNT_KEY
,
"密码错误次数"
));
}
}
@PreAuthorize
(
"@ss.hasPermi('monitor:cache:list')"
)
@PreAuthorize
(
"@ss.hasPermi('monitor:cache:list')"
)
...
...
ruoyi-admin/src/main/resources/application.yml
View file @
aee5d417
...
@@ -39,6 +39,14 @@ logging:
...
@@ -39,6 +39,14 @@ logging:
com.ruoyi
:
debug
com.ruoyi
:
debug
org.springframework
:
warn
org.springframework
:
warn
# 用户配置
user
:
password
:
# 密码最大错误次数
maxRetryCount
:
5
# 密码锁定时间(默认10分钟)
lockTime
:
10
# Spring配置
# Spring配置
spring
:
spring
:
# 资源信息
# 资源信息
...
...
ruoyi-admin/src/main/resources/i18n/messages.properties
View file @
aee5d417
...
@@ -5,7 +5,7 @@ user.jcaptcha.expire=验证码已失效
...
@@ -5,7 +5,7 @@ user.jcaptcha.expire=验证码已失效
user.not.exists
=
用户不存在/密码错误
user.not.exists
=
用户不存在/密码错误
user.password.not.match
=
用户不存在/密码错误
user.password.not.match
=
用户不存在/密码错误
user.password.retry.limit.count
=
密码输入错误{0}次
user.password.retry.limit.count
=
密码输入错误{0}次
user.password.retry.limit.exceed
=
密码输入错误{0}次,帐户锁定
10
分钟
user.password.retry.limit.exceed
=
密码输入错误{0}次,帐户锁定
{1}
分钟
user.password.delete
=
对不起,您的账号已被删除
user.password.delete
=
对不起,您的账号已被删除
user.blocked
=
用户已封禁,请联系管理员
user.blocked
=
用户已封禁,请联系管理员
role.blocked
=
角色已封禁,请联系管理员
role.blocked
=
角色已封禁,请联系管理员
...
...
ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
View file @
aee5d417
...
@@ -36,4 +36,9 @@ public class CacheConstants
...
@@ -36,4 +36,9 @@ public class CacheConstants
* 限流 redis key
* 限流 redis key
*/
*/
public
static
final
String
RATE_LIMIT_KEY
=
"rate_limit:"
;
public
static
final
String
RATE_LIMIT_KEY
=
"rate_limit:"
;
/**
* 登录账户密码错误次数 redis key
*/
public
static
final
String
PWD_ERR_CNT_KEY
=
"pwd_err_cnt:"
;
}
}
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
View file @
aee5d417
...
@@ -74,6 +74,28 @@ public class RedisCache
...
@@ -74,6 +74,28 @@ public class RedisCache
return
redisTemplate
.
expire
(
key
,
timeout
,
unit
);
return
redisTemplate
.
expire
(
key
,
timeout
,
unit
);
}
}
/**
* 获取有效时间
*
* @param key Redis键
* @return 有效时间
*/
public
long
getExpire
(
final
String
key
)
{
return
redisTemplate
.
getExpire
(
key
);
}
/**
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public
Boolean
hasKey
(
String
key
)
{
return
redisTemplate
.
hasKey
(
key
);
}
/**
/**
* 获得缓存的基本对象。
* 获得缓存的基本对象。
*
*
...
...
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/UserPasswordRetryLimitExceedException.java
0 → 100644
View file @
aee5d417
package
com.ruoyi.common.exception.user
;
/**
* 用户错误最大次数异常类
*
* @author ruoyi
*/
public
class
UserPasswordRetryLimitExceedException
extends
UserException
{
private
static
final
long
serialVersionUID
=
1L
;
public
UserPasswordRetryLimitExceedException
(
int
retryLimitCount
,
int
lockTime
)
{
super
(
"user.password.retry.limit.exceed"
,
new
Object
[]
{
retryLimitCount
,
lockTime
});
}
}
ruoyi-framework/src/main/java/com/ruoyi/framework/security/context/AuthenticationContextHolder.java
0 → 100644
View file @
aee5d417
package
com.ruoyi.framework.security.context
;
import
org.springframework.security.core.Authentication
;
/**
* 身份验证信息
*
* @author ruoyi
*/
public
class
AuthenticationContextHolder
{
private
static
final
ThreadLocal
<
Authentication
>
contextHolder
=
new
ThreadLocal
<>();
public
static
Authentication
getContext
()
{
return
contextHolder
.
get
();
}
public
static
void
setContext
(
Authentication
context
)
{
contextHolder
.
set
(
context
);
}
public
static
void
clearContext
()
{
contextHolder
.
remove
();
}
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
View file @
aee5d417
...
@@ -23,6 +23,7 @@ import com.ruoyi.common.utils.StringUtils;
...
@@ -23,6 +23,7 @@ import com.ruoyi.common.utils.StringUtils;
import
com.ruoyi.common.utils.ip.IpUtils
;
import
com.ruoyi.common.utils.ip.IpUtils
;
import
com.ruoyi.framework.manager.AsyncManager
;
import
com.ruoyi.framework.manager.AsyncManager
;
import
com.ruoyi.framework.manager.factory.AsyncFactory
;
import
com.ruoyi.framework.manager.factory.AsyncFactory
;
import
com.ruoyi.framework.security.context.AuthenticationContextHolder
;
import
com.ruoyi.system.service.ISysConfigService
;
import
com.ruoyi.system.service.ISysConfigService
;
import
com.ruoyi.system.service.ISysUserService
;
import
com.ruoyi.system.service.ISysUserService
;
...
@@ -70,9 +71,10 @@ public class SysLoginService
...
@@ -70,9 +71,10 @@ public class SysLoginService
Authentication
authentication
=
null
;
Authentication
authentication
=
null
;
try
try
{
{
UsernamePasswordAuthenticationToken
authenticationToken
=
new
UsernamePasswordAuthenticationToken
(
username
,
password
);
AuthenticationContextHolder
.
setContext
(
authenticationToken
);
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication
=
authenticationManager
authentication
=
authenticationManager
.
authenticate
(
authenticationToken
);
.
authenticate
(
new
UsernamePasswordAuthenticationToken
(
username
,
password
));
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
...
...
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java
0 → 100644
View file @
aee5d417
package
com.ruoyi.framework.web.service
;
import
java.util.concurrent.TimeUnit
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.stereotype.Component
;
import
com.ruoyi.common.constant.CacheConstants
;
import
com.ruoyi.common.constant.Constants
;
import
com.ruoyi.common.core.domain.entity.SysUser
;
import
com.ruoyi.common.core.redis.RedisCache
;
import
com.ruoyi.common.exception.user.UserPasswordNotMatchException
;
import
com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException
;
import
com.ruoyi.common.utils.MessageUtils
;
import
com.ruoyi.common.utils.SecurityUtils
;
import
com.ruoyi.framework.manager.AsyncManager
;
import
com.ruoyi.framework.manager.factory.AsyncFactory
;
import
com.ruoyi.framework.security.context.AuthenticationContextHolder
;
/**
* 登录密码方法
*
* @author ruoyi
*/
@Component
public
class
SysPasswordService
{
@Autowired
private
RedisCache
redisCache
;
@Value
(
value
=
"${user.password.maxRetryCount}"
)
private
int
maxRetryCount
;
@Value
(
value
=
"${user.password.lockTime}"
)
private
int
lockTime
;
/**
* 登录账户密码错误次数缓存键名
*
* @param username 用户名
* @return 缓存键key
*/
private
String
getCacheKey
(
String
username
)
{
return
CacheConstants
.
PWD_ERR_CNT_KEY
+
username
;
}
public
void
validate
(
SysUser
user
)
{
Authentication
usernamePasswordAuthenticationToken
=
AuthenticationContextHolder
.
getContext
();
String
username
=
usernamePasswordAuthenticationToken
.
getName
();
String
password
=
usernamePasswordAuthenticationToken
.
getCredentials
().
toString
();
Integer
retryCount
=
redisCache
.
getCacheObject
(
getCacheKey
(
username
));
if
(
retryCount
==
null
)
{
retryCount
=
0
;
}
if
(
retryCount
>=
Integer
.
valueOf
(
maxRetryCount
).
intValue
())
{
AsyncManager
.
me
().
execute
(
AsyncFactory
.
recordLogininfor
(
username
,
Constants
.
LOGIN_FAIL
,
MessageUtils
.
message
(
"user.password.retry.limit.exceed"
,
maxRetryCount
,
lockTime
)));
throw
new
UserPasswordRetryLimitExceedException
(
maxRetryCount
,
lockTime
);
}
if
(!
matches
(
user
,
password
))
{
retryCount
=
retryCount
+
1
;
AsyncManager
.
me
().
execute
(
AsyncFactory
.
recordLogininfor
(
username
,
Constants
.
LOGIN_FAIL
,
MessageUtils
.
message
(
"user.password.retry.limit.count"
,
retryCount
)));
redisCache
.
setCacheObject
(
getCacheKey
(
username
),
retryCount
,
lockTime
,
TimeUnit
.
MINUTES
);
throw
new
UserPasswordNotMatchException
();
}
else
{
clearLoginRecordCache
(
username
);
}
}
public
boolean
matches
(
SysUser
user
,
String
rawPassword
)
{
return
SecurityUtils
.
matchesPassword
(
rawPassword
,
user
.
getPassword
());
}
public
void
clearLoginRecordCache
(
String
loginName
)
{
if
(
redisCache
.
hasKey
(
getCacheKey
(
loginName
)))
{
redisCache
.
deleteObject
(
getCacheKey
(
loginName
));
}
}
}
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
View file @
aee5d417
...
@@ -26,6 +26,9 @@ public class UserDetailsServiceImpl implements UserDetailsService
...
@@ -26,6 +26,9 @@ public class UserDetailsServiceImpl implements UserDetailsService
@Autowired
@Autowired
private
ISysUserService
userService
;
private
ISysUserService
userService
;
@Autowired
private
SysPasswordService
passwordService
;
@Autowired
@Autowired
private
SysPermissionService
permissionService
;
private
SysPermissionService
permissionService
;
...
@@ -50,6 +53,8 @@ public class UserDetailsServiceImpl implements UserDetailsService
...
@@ -50,6 +53,8 @@ public class UserDetailsServiceImpl implements UserDetailsService
throw
new
ServiceException
(
"对不起,您的账号:"
+
username
+
" 已停用"
);
throw
new
ServiceException
(
"对不起,您的账号:"
+
username
+
" 已停用"
);
}
}
passwordService
.
validate
(
user
);
return
createLoginUser
(
user
);
return
createLoginUser
(
user
);
}
}
...
...
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