shuzheng/zheng · warning · IncorrectCredentialsException

IncorrectCredentialsException

Error message

IncorrectCredentialsException

What it means

UpmsRealm throws Shiro's IncorrectCredentialsException when the stored MD5 hash (MD5(password + salt)) does not match the submitted password's computed hash. The account exists but the password is wrong.

Source

Thrown at zheng-upms/zheng-upms-client/src/main/java/com/zheng/upms/client/shiro/realm/UpmsRealm.java:91

     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String) authenticationToken.getPrincipal();
        String password = new String((char[]) authenticationToken.getCredentials());
        // client无密认证
        String upmsType = PropertiesFileUtil.getInstance("zheng-upms-client").get("zheng.upms.type");
        if ("client".equals(upmsType)) {
            return new SimpleAuthenticationInfo(username, password, getName());
        }

        // 查询用户信息
        UpmsUser upmsUser = upmsApiService.selectUpmsUserByUsername(username);

        if (null == upmsUser) {
            throw new UnknownAccountException();
        }
        if (!upmsUser.getPassword().equals(MD5Util.md5(password + upmsUser.getSalt()))) {
            throw new IncorrectCredentialsException();
        }
        if (upmsUser.getLocked() == 1) {
            throw new LockedAccountException();
        }

        return new SimpleAuthenticationInfo(username, password, getName());
    }

}

View on GitHub (pinned to 7005c0a775)

Solutions

  1. Retry with the correct password and provide a reset-password flow for forgotten ones.
  2. Verify stored password equals MD5Util.md5(password + salt) for the row; re-hash if data was migrated with a different algorithm.
  3. Ensure the same MD5Util/salt concatenation order is used everywhere (registration/update vs. verification).
  4. Catch IncorrectCredentialsException in the login controller and return a user-friendly error.

Example fix

// before
boolean ok = upmsUser.getPassword().equals(MD5Util.md5(password + upmsUser.getSalt())); // throws upstream on mismatch
// after
try {
    currentUser.login(token);
} catch (IncorrectCredentialsException ice) {
    model.addAttribute("error", "密码错误");
    return "login";
}
Defensive patterns

Strategy: try-catch

Validate before calling

UpmsUser u = upmsApiService.selectUpmsUserByUsername(username);
boolean passwordOk = u != null && u.getPassword().equals(MD5Util.md5(password + u.getSalt()));

Try / catch

try {
    currentUser.login(token);
} catch (IncorrectCredentialsException e) {
    model.addAttribute("error", "账号或密码错误");
    return "login";
}

Prevention

When it happens

Trigger: Subject.login with a password whose MD5(password + user.salt) differs from upmsUser.getPassword(); happens on wrong password, or when the salt/hash was changed or migrated inconsistently.

Common situations: User mistypes password; password stored with a different hashing scheme (plain MD5, different salt placement) than the realm expects; user record imported from another system without re-hashing; caps-lock/encoding issues.

Related errors


AI-assisted analysis of shuzheng/zheng@7005c0a775 (2026-09-04). Data as JSON: /api/errors/275dde57e9ea85c5. Report an issue: GitHub.