Index: oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthenticationTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthenticationTest.java (revision 28d0094554ff850786f3430d4103f516b13a9a3c) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthenticationTest.java (revision ) @@ -24,6 +24,8 @@ import javax.jcr.Credentials; import javax.jcr.GuestCredentials; import javax.jcr.SimpleCredentials; +import javax.security.auth.login.AccountNotFoundException; +import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; import org.apache.jackrabbit.api.security.authentication.token.TokenCredentials; @@ -73,17 +75,27 @@ invalid.add(new Credentials() {}); for (Credentials creds : invalid) { - assertFalse(authentication.authenticate(creds)); + try { + authentication.authenticate(creds); + fail("invalid credentials should throw exception"); + } catch (FailedLoginException e) { + // success - } - } + } + } + } @Test public void testAuthenticateCannotResolveUser() throws Exception { SimpleCredentials sc = new SimpleCredentials("unknownUser", "pw".toCharArray()); Authentication a = new UserAuthentication(sc.getUserID(), getUserManager(root)); - assertFalse(a.authenticate(sc)); + try { + a.authenticate(sc); + fail("user should not have been resolved"); + } catch (AccountNotFoundException e) { + // success - } + } + } @Test public void testAuthenticateResolvesToGroup() throws Exception { @@ -94,15 +106,13 @@ try { a.authenticate(sc); fail("Authenticating Group should fail"); - } catch (LoginException e) { + } catch (AccountNotFoundException e) { // success } finally { - if (g != null) { - g.remove(); - root.commit(); - } - } + g.remove(); + root.commit(); + } + } - } @Test public void testAuthenticateInvalidSimpleCredentials() throws Exception { @@ -115,7 +125,7 @@ try { authentication.authenticate(creds); fail("LoginException expected"); - } catch (LoginException e) { + } catch (FailedLoginException e) { // success } } @@ -126,7 +136,7 @@ try { authentication.authenticate(new SimpleCredentials("unknownUser", "pw".toCharArray())); fail("LoginException expected"); - } catch (LoginException e) { + } catch (FailedLoginException e) { // success } } \ No newline at end of file Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthentication.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthentication.java (revision 28d0094554ff850786f3430d4103f516b13a9a3c) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/UserAuthentication.java (revision ) @@ -22,6 +22,9 @@ import javax.jcr.RepositoryException; import javax.jcr.SimpleCredentials; import javax.security.auth.Subject; +import javax.security.auth.login.AccountLockedException; +import javax.security.auth.login.AccountNotFoundException; +import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; import org.apache.jackrabbit.api.security.user.Authorizable; @@ -77,51 +80,50 @@ return false; } - boolean success = false; try { Authorizable authorizable = userManager.getAuthorizable(userId); if (authorizable == null) { - return false; + throw new AccountNotFoundException("Account does not exist: " + userId); } if (authorizable.isGroup()) { - throw new LoginException("Not a user " + userId); + throw new AccountNotFoundException("Not a user " + userId); } User user = (User) authorizable; if (user.isDisabled()) { - throw new LoginException("User with ID " + userId + " has been disabled: "+ user.getDisabledReason()); + throw new AccountLockedException("User with ID " + userId + " has been disabled: "+ user.getDisabledReason()); } if (credentials instanceof SimpleCredentials) { SimpleCredentials creds = (SimpleCredentials) credentials; Credentials userCreds = user.getCredentials(); if (userId.equals(creds.getUserID()) && userCreds instanceof CredentialsImpl) { - success = PasswordUtil.isSame(((CredentialsImpl) userCreds).getPasswordHash(), creds.getPassword()); + if (!PasswordUtil.isSame(((CredentialsImpl) userCreds).getPasswordHash(), creds.getPassword())) { + throw new FailedLoginException("UserId/password mismatch"); - } + } - checkSuccess(success, "UserId/Password mismatch."); + } else { + throw new FailedLoginException("UserId mismatch"); + } } else if (credentials instanceof ImpersonationCredentials) { ImpersonationCredentials ipCreds = (ImpersonationCredentials) credentials; AuthInfo info = ipCreds.getImpersonatorInfo(); - success = equalUserId(ipCreds) && impersonate(info, user); - checkSuccess(success, "Impersonation not allowed."); + if (!equalUserId(ipCreds) || !impersonate(info, user)) { + throw new FailedLoginException("Impersonation not allowed"); + } } else { // guest login is allowed if an anonymous user exists in the content (see get user above) - success = (credentials instanceof GuestCredentials) || credentials == PRE_AUTHENTICATED; + if (!(credentials instanceof GuestCredentials) || credentials == PRE_AUTHENTICATED) { + throw new FailedLoginException("Credentials neither pre-authenticated nor guest"); - } + } + } } catch (RepositoryException e) { throw new LoginException(e.getMessage()); } - return success; + return true; } //-------------------------------------------------------------------------- - private static void checkSuccess(boolean success, String msg) throws LoginException { - if (!success) { - throw new LoginException(msg); - } - } - private boolean equalUserId(ImpersonationCredentials creds) { Credentials base = creds.getBaseCredentials(); return (base instanceof SimpleCredentials) && userId.equals(((SimpleCredentials) base).getUserID()); \ No newline at end of file