@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        if (!(token instanceof UsernamePasswordToken)) {
            throw new AuthenticationException();
        }

        final UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        char[] password = usernamePasswordToken.getPassword();

        // lookup from database, for roles/perms, but also
        // determine how to authenticate (delegate or local), whether disabled
        final PrincipalForApplicationUser principal = lookupPrincipal(username,
                (hasDelegateAuthenticationRealm() && getAutoCreateUser()));
        if (principal == null) {
            // if no delegate authentication
            throw new CredentialsException("Unknown user/password combination");
        }

        if (principal.isDisabled()) {
            // this is the default if delegated account and automatically created
            throw new DisabledAccountException();
        }

        if(principal.getAccountType() == AccountType.DELEGATED) {
            AuthenticationInfo delegateAccount = null;
            if (hasDelegateAuthenticationRealm()) {
                try {
                    delegateAccount = delegateAuthenticationRealm.getAuthenticationInfo(token);
                } catch (AuthenticationException ex) {
                    // fall through
                }
            }
            if(delegateAccount == null) {
                throw new CredentialsException("Unknown user/password combination");
            }
        } else {
            final CheckPasswordResult result = checkPassword(password, principal.getEncryptedPassword());
            switch (result) {
                case OK:
                    break;
                case BAD_PASSWORD:
                    throw new CredentialsException("Unknown user/password combination");
                case NO_PASSWORD_ENCRYPTION_SERVICE_CONFIGURED:
                    throw new AuthenticationException("No password encryption service is installed");
                default:
                    throw new AuthenticationException();
            }
        }

        final Object credentials = token.getCredentials();
        final String realmName = getName();
        return new AuthInfoForApplicationUser(principal, realmName, credentials);
    }
@ Override protected AuthenticationInfo doGetAuthenticationInfo ( AuthenticationToken token ) throws AuthenticationException { if ( ! ( token instanceof UsernamePasswordToken ) ) { throw new AuthenticationException ( ) ; } final UsernamePasswordToken usernamePasswordToken = ( UsernamePasswordToken ) token ; String username = usernamePasswordToken . getUsername ( ) ; char [ ] password = usernamePasswordToken . getPassword ( ) ; final PrincipalForApplicationUser principal = lookupPrincipal ( username , ( hasDelegateAuthenticationRealm ( ) && getAutoCreateUser ( ) ) ) ; if ( principal == null ) { throw new CredentialsException ( "Unknown user/password combination" ) ; } if ( principal . isDisabled ( ) ) { throw new DisabledAccountException ( ) ; } if ( principal . getAccountType ( ) == AccountType . DELEGATED ) { AuthenticationInfo delegateAccount = null ; if ( hasDelegateAuthenticationRealm ( ) ) { try { delegateAccount = delegateAuthenticationRealm . getAuthenticationInfo ( token ) ; } catch ( AuthenticationException ex ) { } } if ( delegateAccount == null ) { throw new CredentialsException ( "Unknown user/password combination" ) ; } } else { final CheckPasswordResult result = checkPassword ( password , principal . getEncryptedPassword ( ) ) ; switch ( result ) { case OK : break ; case BAD_PASSWORD : throw new CredentialsException ( "Unknown user/password combination" ) ; case NO_PASSWORD_ENCRYPTION_SERVICE_CONFIGURED : throw new AuthenticationException ( "No password encryption service is installed" ) ; default : throw new AuthenticationException ( ) ; } } final Object credentials = token . getCredentials ( ) ; final String realmName = getName ( ) ; return new AuthInfoForApplicationUser ( principal , realmName , credentials ) ; }
In order to provide an attacker with additional information, the exceptions thrown here deliberately have
few (or no) details in their exception message.  Similarly, the generic
{@link org.apache.shiro.authc.CredentialsException} is thrown for both a non-existent user and also an
invalid password.