wuyouzhuguli/SpringAll · error · LockedAccountException
账号已被锁定,请联系管理员!
Error message
账号已被锁定,请联系管理员!
What it means
Apache Shiro's LockedAccountException (subclass of AccountException -> AuthenticationException), thrown by a Realm inside doGetAuthenticationInfo when an authenticated principal's account is administratively disabled. Here ShiroRealm throws it AFTER the username lookup and password match both succeed, when the DB row's status column equals "0". Shiro's Authenticator propagates it to Subject.login(token), where it surfaces as an AuthenticationException the caller must catch.
Source
Thrown at 17.Spring-Boot-Shiro-Session/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
- Have an administrator set the user's status to the active value (non-"0", typically "1") in sys_user.
- In your login controller, catch LockedAccountException distinctly from IncorrectCredentialsException/UnknownAccountException so the user sees a 'contact admin' message.
- Confirm the status column semantics in the User entity/table (which value means active) and that new accounts are created with the active status.
- If status can be null, guard with "0".equals(user.getStatus()) to avoid an NPE masking the real state.
Example fix
// before
try {
subject.login(token);
} catch (AuthenticationException e) {
// every failure looks identical to the user
return "login failed";
}
// after
try {
subject.login(token);
} catch (LockedAccountException e) {
return "account locked, contact admin";
} catch (UnknownAccountException | IncorrectCredentialsException e) {
return "bad username or password";
} Defensive patterns
Strategy: try-catch
Try / catch
try {
subject.login(token);
} catch (LockedAccountException e) {
// account is disabled - surface a 'contact admin' message, do NOT reveal which field was wrong
return Result.fail("账号已被锁定,请联系管理员");
} catch (UnknownAccountException | IncorrectCredentialsException e) {
return Result.fail("用户名或密码错误");
} Prevention
- Create new accounts with the active status value by default so logins are not accidentally locked.
- Keep distinct catch branches per Shiro AuthenticationException subtype rather than one broad catch.
- Do not expose whether the failure was 'locked' vs 'bad credentials' to untrusted callers if account enumeration is a concern.
When it happens
Trigger: Subject.login(new UsernamePasswordToken(userName, password)) where userName+password are correct but the user row has status = "0". Equivalent to: the admin locked the account in the sys_user table.
Common situations: An administrator set user.status to 0 to disable the account; status field uses "0"=locked/"1"=active and a new/seeded user defaults to locked; a brute-force lockout policy flipped the flag; the status column is null causing an NPE instead on this same line.
Related errors
AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14).
Data as JSON: /api/errors/36171ba2279d58cb.
Report an issue: GitHub.