wuyouzhuguli/SpringAll · warning · LockedAccountException
账号已被锁定,请联系管理员!
Error message
账号已被锁定,请联系管理员!
What it means
LockedAccountException (extends AccountException -> AuthenticationException) is thrown when an account exists and credentials are valid but the account is administratively disabled. Here the gate is user.getStatus().equals("0") - a CHAR(1) status where '0' means locked - and it fires only after both the user lookup and password check pass. The message directs the user to contact an administrator.
Source
Thrown at 15.Spring-Boot-Shiro-Ehcache/src/main/java/com/springboot/shiro/ShiroRealm.java:84
/**
* 登录认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
System.out.println("用户" + userName + "认证-----ShiroRealm.doGetAuthenticationInfo");
User user = userMapper.findByUserName(userName);
if (user == null) {
throw new UnknownAccountException("用户名或密码错误!");
}
if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException("用户名或密码错误!");
}
if (user.getStatus().equals("0")) {
throw new LockedAccountException("账号已被锁定,请联系管理员!");
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
return info;
}
}
View on GitHub (pinned to 614d2578d9)
Solutions
- Unlock the account in the DB: UPDATE T_USER SET STATUS='1' WHERE USERNAME='<user>'; (STATUS CHAR(1): '1'=active, '0'=locked).
- Use the active seeded account 'mrbird' (STATUS='1') instead of 'test' (STATUS='0', locked).
- Confirm init.sql seeds STATUS correctly; do not default new accounts to '0'.
- Provide an admin unlock screen/API so locked accounts can be re-enabled operationally.
- Clear the Redis/Ehcache authorization/session cache after changing STATUS so the stale locked value is not served.
Example fix
-- before: account is locked SELECT username, status FROM t_user WHERE username = 'test'; -- status = '0' -- after: unlock the account (STATUS CHAR(1): 1 = active) UPDATE t_user SET status = '1' WHERE username = 'test'; COMMIT;
Defensive patterns
Strategy: try-catch
Validate before calling
// Optional pre-check of status (after existence confirmed) to fail fast
User u = userMapper.findByUserName(username);
if (u != null && "0".equals(u.getStatus())) {
return ResponseBo.error("账号已被锁定,请联系管理员!");
} Type guard
static boolean isActive(User u) {
return u != null && "1".equals(u.getStatus());
} Try / catch
try {
SecurityUtils.getSubject().login(
new UsernamePasswordToken(username, password));
} catch (LockedAccountException e) {
return ResponseBo.error("账号已被锁定,请联系管理员!");
} catch (AuthenticationException e) {
return ResponseBo.error("用户名或密码错误!");
} Prevention
- Default new accounts to STATUS='1' (active) in init.sql/migrations; '0' means locked.
- Invalidate the Redis/Ehcache authorization cache after any STATUS change.
- Add an admin unlock workflow for operational lockouts.
- Treat CHAR(1) '0' as locked consistently across every module.
- Remember the seeded 'test' account is intentionally locked; use 'mrbird' for smoke tests.
When it happens
Trigger: Logging in with a correct username AND correct password, but the T_USER row has STATUS='0' in the database (set by the seed - the 'test' account - manually, or flipped by lockout logic). Because this check runs after the credential check, an incorrect password masks the locked state. Context: the Ehcache module.
Common situations: Ehcache auth cache was not cleared after STATUS changed to '0', so lock state is inconsistent; or the seed set STATUS='0' (the 'test' account).
Related errors
AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14).
Data as JSON: /api/errors/a262872d0ad350fd.
Report an issue: GitHub.