Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
sts网站
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
liyang
sts网站
Commits
aee5d417
Commit
aee5d417
authored
Jul 30, 2022
by
RuoYi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
支持配置密码最大错误次数/锁定时间
parent
250c5ba2
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
184 additions
and
3 deletions
+184
-3
CacheController.java
...ava/com/ruoyi/web/controller/monitor/CacheController.java
+1
-0
application.yml
ruoyi-admin/src/main/resources/application.yml
+8
-0
messages.properties
ruoyi-admin/src/main/resources/i18n/messages.properties
+1
-1
CacheConstants.java
...c/main/java/com/ruoyi/common/constant/CacheConstants.java
+5
-0
RedisCache.java
...src/main/java/com/ruoyi/common/core/redis/RedisCache.java
+22
-0
UserPasswordRetryLimitExceedException.java
...exception/user/UserPasswordRetryLimitExceedException.java
+16
-0
AuthenticationContextHolder.java
...amework/security/context/AuthenticationContextHolder.java
+28
-0
SysLoginService.java
...java/com/ruoyi/framework/web/service/SysLoginService.java
+4
-2
SysPasswordService.java
...a/com/ruoyi/framework/web/service/SysPasswordService.java
+94
-0
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
caches
.
add
(
new
SysCache
(
CacheConstants
.
CAPTCHA_CODE_KEY
,
"验证码"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
REPEAT_SUBMIT_KEY
,
"防重提交"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
RATE_LIMIT_KEY
,
"限流处理"
));
caches
.
add
(
new
SysCache
(
CacheConstants
.
PWD_ERR_CNT_KEY
,
"密码错误次数"
));
}
@PreAuthorize
(
"@ss.hasPermi('monitor:cache:list')"
)
...
...
ruoyi-admin/src/main/resources/application.yml
View file @
aee5d417
...
...
@@ -39,6 +39,14 @@ logging:
com.ruoyi
:
debug
org.springframework
:
warn
# 用户配置
user
:
password
:
# 密码最大错误次数
maxRetryCount
:
5
# 密码锁定时间(默认10分钟)
lockTime
:
10
# Spring配置
spring
:
# 资源信息
...
...
ruoyi-admin/src/main/resources/i18n/messages.properties
View file @
aee5d417
...
...
@@ -5,7 +5,7 @@ user.jcaptcha.expire=验证码已失效
user.not.exists
=
用户不存在/密码错误
user.password.not.match
=
用户不存在/密码错误
user.password.retry.limit.count
=
密码输入错误{0}次
user.password.retry.limit.exceed
=
密码输入错误{0}次,帐户锁定
10
分钟
user.password.retry.limit.exceed
=
密码输入错误{0}次,帐户锁定
{1}
分钟
user.password.delete
=
对不起,您的账号已被删除
user.blocked
=
用户已封禁,请联系管理员
role.blocked
=
角色已封禁,请联系管理员
...
...
ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
View file @
aee5d417
...
...
@@ -36,4 +36,9 @@ public class CacheConstants
* 限流 redis key
*/
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
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;
import
com.ruoyi.common.utils.ip.IpUtils
;
import
com.ruoyi.framework.manager.AsyncManager
;
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.ISysUserService
;
...
...
@@ -70,9 +71,10 @@ public class SysLoginService
Authentication
authentication
=
null
;
try
{
UsernamePasswordAuthenticationToken
authenticationToken
=
new
UsernamePasswordAuthenticationToken
(
username
,
password
);
AuthenticationContextHolder
.
setContext
(
authenticationToken
);
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication
=
authenticationManager
.
authenticate
(
new
UsernamePasswordAuthenticationToken
(
username
,
password
));
authentication
=
authenticationManager
.
authenticate
(
authenticationToken
);
}
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
@Autowired
private
ISysUserService
userService
;
@Autowired
private
SysPasswordService
passwordService
;
@Autowired
private
SysPermissionService
permissionService
;
...
...
@@ -50,6 +53,8 @@ public class UserDetailsServiceImpl implements UserDetailsService
throw
new
ServiceException
(
"对不起,您的账号:"
+
username
+
" 已停用"
);
}
passwordService
.
validate
(
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