{"record":{"id":"36171ba2279d58cb","repo":"wuyouzhuguli/SpringAll","slug":"error-36171b","errorCode":null,"errorMessage":"账号已被锁定,请联系管理员！","messagePattern":"账号已被锁定,请联系管理员！","errorType":"exception","errorClass":"LockedAccountException","httpStatus":null,"severity":"error","filePath":"17.Spring-Boot-Shiro-Session/src/main/java/com/springboot/shiro/ShiroRealm.java","lineNumber":84,"sourceCode":"\t/**\n\t * 登录认证\n\t */\n\t@Override\n\tprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {\n\t\tString userName = (String) token.getPrincipal();\n\t\tString password = new String((char[]) token.getCredentials());\n\n\t\tSystem.out.println(\"用户\" + userName + \"认证-----ShiroRealm.doGetAuthenticationInfo\");\n\t\tUser user = userMapper.findByUserName(userName);\n\n\t\tif (user == null) {\n\t\t\tthrow new UnknownAccountException(\"用户名或密码错误！\");\n\t\t}\n\t\tif (!password.equals(user.getPassword())) {\n\t\t\tthrow new IncorrectCredentialsException(\"用户名或密码错误！\");\n\t\t}\n\t\tif (user.getStatus().equals(\"0\")) {\n\t\t\tthrow new LockedAccountException(\"账号已被锁定,请联系管理员！\");\n\t\t}\n\t\tSimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());\n\t\treturn info;\n\t}\n\n}\n","sourceCodeStart":66,"sourceCodeEnd":91,"githubUrl":"https://github.com/wuyouzhuguli/SpringAll/blob/614d2578d9495acf53cc02f2dee9c6131cc5e51a/17.Spring-Boot-Shiro-Session/src/main/java/com/springboot/shiro/ShiroRealm.java#L66-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ntry {\n    subject.login(token);\n} catch (AuthenticationException e) {\n    // every failure looks identical to the user\n    return \"login failed\";\n}\n\n// after\ntry {\n    subject.login(token);\n} catch (LockedAccountException e) {\n    return \"account locked, contact admin\";\n} catch (UnknownAccountException | IncorrectCredentialsException e) {\n    return \"bad username or password\";\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    subject.login(token);\n} catch (LockedAccountException e) {\n    // account is disabled - surface a 'contact admin' message, do NOT reveal which field was wrong\n    return Result.fail(\"账号已被锁定,请联系管理员\");\n} catch (UnknownAccountException | IncorrectCredentialsException e) {\n    return Result.fail(\"用户名或密码错误\");\n}","preventionTips":["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."],"tags":["shiro","authentication","account-locked","security"],"backgroundTag":null,"analyzedSha":"614d2578d9495acf53cc02f2dee9c6131cc5e51a","analyzedAt":"2026-08-14T04:40:03.488Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}