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

  1. Have an administrator set the user's status to the active value (non-"0", typically "1") in sys_user.
  2. In your login controller, catch LockedAccountException distinctly from IncorrectCredentialsException/UnknownAccountException so the user sees a 'contact admin' message.
  3. Confirm the status column semantics in the User entity/table (which value means active) and that new accounts are created with the active status.
  4. 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

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.