{"record":{"id":"bd493fe4f2be88ab","repo":"wuyouzhuguli/SpringAll","slug":"error-bd493f","errorCode":null,"errorMessage":"账号已被锁定,请联系管理员！","messagePattern":"账号已被锁定,请联系管理员！","errorType":"exception","errorClass":"LockedAccountException","httpStatus":null,"severity":"warning","filePath":"16.Spring-Boot-Shiro-Thymeleaf-Tag/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/16.Spring-Boot-Shiro-Thymeleaf-Tag/src/main/java/com/springboot/shiro/ShiroRealm.java#L66-L91","documentation":"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.","triggerScenarios":"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 Shiro Thymeleaf-tag module.","commonSituations":"The Thymeleaf-tag demo account is locked (STATUS='0', e.g. the 'test' seed) so login blocks before any tag renders; the template shows the locked message.","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."],"exampleFix":"-- before: account is locked\nSELECT username, status FROM t_user WHERE username = 'test';\n-- status = '0'\n-- after: unlock the account (STATUS CHAR(1): 1 = active)\nUPDATE t_user SET status = '1' WHERE username = 'test';\nCOMMIT;","handlingStrategy":"try-catch","validationCode":"// Optional pre-check of status (after existence confirmed) to fail fast\nUser u = userMapper.findByUserName(username);\nif (u != null && \"0\".equals(u.getStatus())) {\n    return ResponseBo.error(\"账号已被锁定,请联系管理员！\");\n}","typeGuard":"static boolean isActive(User u) {\n    return u != null && \"1\".equals(u.getStatus());\n}","tryCatchPattern":"try {\n    SecurityUtils.getSubject().login(\n        new UsernamePasswordToken(username, password));\n} catch (LockedAccountException e) {\n    return ResponseBo.error(\"账号已被锁定,请联系管理员！\");\n} catch (AuthenticationException e) {\n    return ResponseBo.error(\"用户名或密码错误！\");\n}","preventionTips":["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."],"tags":["shiro","authentication","locked-account","java","spring-boot","thymeleaf"],"backgroundTag":null,"analyzedSha":"614d2578d9495acf53cc02f2dee9c6131cc5e51a","analyzedAt":"2026-08-14T04:40:03.488Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}