{"record":{"id":"8777fd707ca69d99","repo":"shuzheng/zheng","slug":"lockedaccountexception","errorCode":null,"errorMessage":"LockedAccountException","messagePattern":"LockedAccountException","errorType":"exception","errorClass":"LockedAccountException","httpStatus":null,"severity":"warning","filePath":"zheng-upms/zheng-upms-client/src/main/java/com/zheng/upms/client/shiro/realm/UpmsRealm.java","lineNumber":94,"sourceCode":"        String username = (String) authenticationToken.getPrincipal();\n        String password = new String((char[]) authenticationToken.getCredentials());\n        // client无密认证\n        String upmsType = PropertiesFileUtil.getInstance(\"zheng-upms-client\").get(\"zheng.upms.type\");\n        if (\"client\".equals(upmsType)) {\n            return new SimpleAuthenticationInfo(username, password, getName());\n        }\n\n        // 查询用户信息\n        UpmsUser upmsUser = upmsApiService.selectUpmsUserByUsername(username);\n\n        if (null == upmsUser) {\n            throw new UnknownAccountException();\n        }\n        if (!upmsUser.getPassword().equals(MD5Util.md5(password + upmsUser.getSalt()))) {\n            throw new IncorrectCredentialsException();\n        }\n        if (upmsUser.getLocked() == 1) {\n            throw new LockedAccountException();\n        }\n\n        return new SimpleAuthenticationInfo(username, password, getName());\n    }\n\n}\n","sourceCodeStart":76,"sourceCodeEnd":101,"githubUrl":"https://github.com/shuzheng/zheng/blob/7005c0a775e6d014d1dc8a8a809f7b1c13bf785a/zheng-upms/zheng-upms-client/src/main/java/com/zheng/upms/client/shiro/realm/UpmsRealm.java#L76-L101","documentation":"UpmsRealm throws Shiro's LockedAccountException when the authenticated user exists and the password matches but upmsUser.getLocked() == 1, meaning the account has been administratively disabled. Authentication is denied even with correct credentials.","triggerScenarios":"Subject.login for a user whose upms_user.locked column is 1 — typically after an admin locked the account or too many failed attempts set the flag.","commonSituations":"Admin disabled a user in the UPMS management console; account locked by security policy; test account left locked; environment DB copy contains locked users.","solutions":["Set locked = 0 for the user in the upms_user table (or via the admin UI) if the lock is no longer warranted.","Inform the user to contact an administrator to unlock the account.","Catch LockedAccountException in the login controller and show an 'account is locked' message distinct from wrong password.","Review why the account was locked (failed attempts, admin action) before unlocking."],"exampleFix":"// before\ncurrentUser.login(token); // throws LockedAccountException\n// after\ntry {\n    currentUser.login(token);\n} catch (LockedAccountException lae) {\n    model.addAttribute(\"error\", \"账号已被锁定，请联系管理员\");\n    return \"login\";\n}","handlingStrategy":"try-catch","validationCode":"UpmsUser u = upmsApiService.selectUpmsUserByUsername(username);\nif (u != null && u.getLocked() == 1) {\n    // short-circuit: inform user the account is locked\n}","typeGuard":"boolean isLocked(UpmsUser u) {\n    return u != null && u.getLocked() != null && u.getLocked() == 1;\n}","tryCatchPattern":"try {\n    currentUser.login(token);\n} catch (LockedAccountException e) {\n    model.addAttribute(\"error\", \"账号已被锁定，请联系管理员\");\n    return \"login\";\n}","preventionTips":["Catch LockedAccountException separately to give a distinct, actionable message.","Provide an admin workflow to unlock accounts and audit why they were locked.","Notify users when their account is locked rather than silently failing.","Track failed-attempt counts and auto-unlock policies to reduce support load.","Keep test/un environments' accounts unlocked to avoid confusing failures."],"tags":["authentication","shiro","account-locked","login"],"backgroundTag":"account-locked","analyzedSha":"7005c0a775e6d014d1dc8a8a809f7b1c13bf785a","analyzedAt":"2026-09-04T16:58:32.852Z","contentChangedAt":"2026-09-04T16:58:32.852Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}