OPEN - issue SEC-1136: Removed SpringSecurityException. Introduced new AclException as base class for Acl module. Refactored JAAS authentication to map to AuthenticationExcpetions rather than SpringSecurityException. Modified ExceptionTranslationFilter to look explicitly for AuthenticationException or AccessDeniedException (which it should do since these are the only two it handles).

This commit is contained in:
Luke Taylor 2009-04-13 14:56:49 +00:00
parent ca7d055c2b
commit 10673780db
19 changed files with 80 additions and 67 deletions

View File

@ -0,0 +1,34 @@
package org.springframework.security.acls;
import org.springframework.core.NestedRuntimeException;
/**
* Abstract superclass for all exceptions thrown in the acls package and subpackages.
*
* @author Luke Taylor
* @version $Id$
* @since 2.5
*/
public abstract class AclException extends NestedRuntimeException {
/**
* Constructs an <code>AclException</code> with the specified
* message and root cause.
*
* @param msg the detail message
* @param t the root cause
*/
public AclException(String msg, Throwable cause) {
super(msg, cause);
}
/**
* Constructs an <code>AclException</code> with the specified
* message and no root cause.
*
* @param msg the detail message
*/
public AclException(String msg) {
super(msg);
}
}

View File

@ -14,16 +14,13 @@
*/ */
package org.springframework.security.acls; package org.springframework.security.acls;
import org.springframework.security.core.SpringSecurityException;
/** /**
* Thrown if an <code>Acl</code> entry already exists for the object. * Thrown if an <code>Acl</code> entry already exists for the object.
* *
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class AlreadyExistsException extends SpringSecurityException { public class AlreadyExistsException extends AclException {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**

View File

@ -14,16 +14,13 @@
*/ */
package org.springframework.security.acls; package org.springframework.security.acls;
import org.springframework.security.core.SpringSecurityException;
/** /**
* Thrown if an {@link Acl} cannot be deleted because children <code>Acl</code>s exist. * Thrown if an {@link Acl} cannot be deleted because children <code>Acl</code>s exist.
* *
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class ChildrenExistException extends SpringSecurityException { public class ChildrenExistException extends AclException {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**

View File

@ -14,16 +14,13 @@
*/ */
package org.springframework.security.acls; package org.springframework.security.acls;
import org.springframework.security.core.SpringSecurityException;
/** /**
* Thrown if an ACL identity could not be extracted from an object. * Thrown if an ACL identity could not be extracted from an object.
* *
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class IdentityUnavailableException extends SpringSecurityException { public class IdentityUnavailableException extends AclException {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**

View File

@ -14,16 +14,13 @@
*/ */
package org.springframework.security.acls; package org.springframework.security.acls;
import org.springframework.security.core.SpringSecurityException;
/** /**
* Thrown if an ACL-related object cannot be found. * Thrown if an ACL-related object cannot be found.
* *
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class NotFoundException extends SpringSecurityException { public class NotFoundException extends AclException {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**

View File

@ -14,9 +14,6 @@
*/ */
package org.springframework.security.acls; package org.springframework.security.acls;
import org.springframework.security.core.SpringSecurityException;
/** /**
* Thrown if an {@link Acl} cannot perform an operation because it only loaded a subset of <code>Sid</code>s and * Thrown if an {@link Acl} cannot perform an operation because it only loaded a subset of <code>Sid</code>s and
* the caller has requested details for an unloaded <code>Sid</code>. * the caller has requested details for an unloaded <code>Sid</code>.
@ -24,7 +21,7 @@ import org.springframework.security.core.SpringSecurityException;
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class UnloadedSidException extends SpringSecurityException { public class UnloadedSidException extends AclException {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**

View File

@ -1,14 +1,13 @@
package org.springframework.security.config; package org.springframework.security.config;
import org.springframework.security.core.SpringSecurityException; import org.springframework.core.NestedRuntimeException;
/** /**
* @author Luke Taylor * @author Luke Taylor
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class SecurityConfigurationException extends SpringSecurityException { public class SecurityConfigurationException extends NestedRuntimeException {
public SecurityConfigurationException(String s) { public SecurityConfigurationException(String s) {
super(s); super(s);
} }

View File

@ -15,8 +15,8 @@
package org.springframework.security.access; package org.springframework.security.access;
import org.springframework.core.NestedRuntimeException;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.SpringSecurityException;
/** /**
* Thrown if an {@link Authentication} object does not hold a required authority. * Thrown if an {@link Authentication} object does not hold a required authority.
@ -24,7 +24,7 @@ import org.springframework.security.core.SpringSecurityException;
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class AccessDeniedException extends SpringSecurityException { public class AccessDeniedException extends NestedRuntimeException {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**

View File

@ -51,7 +51,4 @@ public class BadCredentialsException extends AuthenticationException {
public BadCredentialsException(String msg, Throwable t) { public BadCredentialsException(String msg, Throwable t) {
super(msg, t); super(msg, t);
} }
//~ Methods ========================================================================================================
} }

View File

@ -16,7 +16,7 @@
package org.springframework.security.authentication.jaas; package org.springframework.security.authentication.jaas;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.SpringSecurityException; import org.springframework.security.core.AuthenticationException;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
@ -30,7 +30,7 @@ import javax.security.auth.login.LoginException;
public class DefaultLoginExceptionResolver implements LoginExceptionResolver { public class DefaultLoginExceptionResolver implements LoginExceptionResolver {
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public SpringSecurityException resolveException(LoginException e) { public AuthenticationException resolveException(LoginException e) {
return new AuthenticationServiceException(e.getMessage(), e); return new AuthenticationServiceException(e.getMessage(), e);
} }
} }

View File

@ -218,7 +218,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, Appli
return result; return result;
} catch (LoginException loginException) { } catch (LoginException loginException) {
SpringSecurityException ase = loginExceptionResolver.resolveException(loginException); AuthenticationException ase = loginExceptionResolver.resolveException(loginException);
publishFailureEvent(request, ase); publishFailureEvent(request, ase);
throw ase; throw ase;
@ -354,7 +354,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, Appli
* @param token The {@link UsernamePasswordAuthenticationToken} being processed * @param token The {@link UsernamePasswordAuthenticationToken} being processed
* @param ase The {@link SpringSecurityException} that caused the failure * @param ase The {@link SpringSecurityException} that caused the failure
*/ */
protected void publishFailureEvent(UsernamePasswordAuthenticationToken token, SpringSecurityException ase) { protected void publishFailureEvent(UsernamePasswordAuthenticationToken token, AuthenticationException ase) {
applicationEventPublisher.publishEvent(new JaasAuthenticationFailedEvent(token, ase)); applicationEventPublisher.publishEvent(new JaasAuthenticationFailedEvent(token, ase));
} }

View File

@ -15,15 +15,15 @@
package org.springframework.security.authentication.jaas; package org.springframework.security.authentication.jaas;
import org.springframework.security.core.SpringSecurityException; import org.springframework.security.core.AuthenticationException;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
/** /**
* The JaasAuthenticationProvider takes an instance of LoginExceptionResolver * The JaasAuthenticationProvider takes an instance of LoginExceptionResolver
* to resolve LoginModule specific exceptions to Spring Security exceptions. For * to resolve LoginModule specific exceptions to Spring Security <tt>AuthenticationException</tt>s.
* instance, a configured login module could throw a * For instance, a configured login module could throw a
* ScrewedUpPasswordException that extends LoginException, in this instance * ScrewedUpPasswordException that extends LoginException, in this instance
* the LoginExceptionResolver implementation would return a {@link * the LoginExceptionResolver implementation would return a {@link
* org.springframework.security.authentication.BadCredentialsException}. * org.springframework.security.authentication.BadCredentialsException}.
@ -39,7 +39,7 @@ public interface LoginExceptionResolver {
* *
* @param e The LoginException thrown by the configured LoginModule. * @param e The LoginException thrown by the configured LoginModule.
* *
* @return The SpringSecurityException that the JaasAuthenticationProvider should throw. * @return The AuthenticationException that the JaasAuthenticationProvider should throw.
*/ */
SpringSecurityException resolveException(LoginException e); AuthenticationException resolveException(LoginException e);
} }

View File

@ -15,21 +15,22 @@
package org.springframework.security.authentication.rcp; package org.springframework.security.authentication.rcp;
import org.springframework.security.core.SpringSecurityException; import org.springframework.core.NestedRuntimeException;
/** /**
* Thrown if a <code>RemoteAuthenticationManager</code> cannot validate the presented authentication request.<P>This * Thrown if a <code>RemoteAuthenticationManager</code> cannot validate the presented authentication request.
* is thrown rather than the normal <code>AuthenticationException</code> because <code>AuthenticationException</code> * <p>
* contains additional properties which may cause issues for the remoting protocol.</p> * This is thrown rather than the normal <code>AuthenticationException</code> because
* <code>AuthenticationException</code> contains additional properties which may cause issues for
* the remoting protocol.
* *
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class RemoteAuthenticationException extends SpringSecurityException { public class RemoteAuthenticationException extends NestedRuntimeException {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**
* Constructs a <code>RemoteAuthenticationException</code> with the * Constructs a <code>RemoteAuthenticationException</code> with the
* specified message and no root cause. * specified message and no root cause.
* *

View File

@ -15,6 +15,8 @@
package org.springframework.security.core; package org.springframework.security.core;
import org.springframework.core.NestedRuntimeException;
/** /**
* Abstract superclass for all exceptions related to an {@link Authentication} object being invalid for whatever * Abstract superclass for all exceptions related to an {@link Authentication} object being invalid for whatever
@ -23,7 +25,7 @@ package org.springframework.security.core;
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public abstract class AuthenticationException extends SpringSecurityException { public abstract class AuthenticationException extends NestedRuntimeException {
//~ Instance fields ================================================================================================ //~ Instance fields ================================================================================================
private Authentication authentication; private Authentication authentication;

View File

@ -15,7 +15,7 @@
package org.springframework.security.userdetails; package org.springframework.security.userdetails;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.AuthenticationException;
/** /**
@ -24,7 +24,7 @@ import org.springframework.security.authentication.BadCredentialsException;
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
*/ */
public class UsernameNotFoundException extends BadCredentialsException { public class UsernameNotFoundException extends AuthenticationException {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**

View File

@ -23,8 +23,8 @@ import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.DESedeKeySpec;
import org.springframework.security.core.SpringSecurityException;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.springframework.core.NestedRuntimeException;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -150,7 +150,7 @@ public final class EncryptionUtils {
Assert.isTrue(key.length() >= 24, "Key must be at least 24 characters long"); Assert.isTrue(key.length() >= 24, "Key must be at least 24 characters long");
} }
public static class EncryptionException extends SpringSecurityException { public static class EncryptionException extends NestedRuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public EncryptionException(String message, Throwable t) { public EncryptionException(String message, Throwable t) {

View File

@ -41,7 +41,6 @@ import org.springframework.security.core.AuthorityUtils;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.GrantedAuthorityImpl; import org.springframework.security.core.GrantedAuthorityImpl;
import org.springframework.security.core.SessionDestroyedEvent; import org.springframework.security.core.SessionDestroyedEvent;
import org.springframework.security.core.SpringSecurityException;
import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.security.core.context.SecurityContextImpl;
@ -187,7 +186,7 @@ public class JaasAuthenticationProviderTests extends TestCase {
public void testLoginExceptionResolver() { public void testLoginExceptionResolver() {
assertNotNull(jaasProvider.getLoginExceptionResolver()); assertNotNull(jaasProvider.getLoginExceptionResolver());
jaasProvider.setLoginExceptionResolver(new LoginExceptionResolver() { jaasProvider.setLoginExceptionResolver(new LoginExceptionResolver() {
public SpringSecurityException resolveException(LoginException e) { public AuthenticationException resolveException(LoginException e) {
return new LockedException("This is just a test!"); return new LockedException("This is just a test!");
} }
}); });

View File

@ -34,7 +34,6 @@ import org.springframework.security.core.AuthorityUtils;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.ldap.LdapAuthenticator; import org.springframework.security.ldap.LdapAuthenticator;
import org.springframework.security.ldap.LdapAuthoritiesPopulator; import org.springframework.security.ldap.LdapAuthoritiesPopulator;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper; import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;
import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UsernameNotFoundException; import org.springframework.security.userdetails.UsernameNotFoundException;
@ -89,7 +88,7 @@ public class LdapAuthenticationProviderTests {
ldapProvider.authenticate(new UsernamePasswordAuthenticationToken("jen", "")); ldapProvider.authenticate(new UsernamePasswordAuthenticationToken("jen", ""));
} }
@Test @Test(expected=BadCredentialsException.class)
public void usernameNotFoundExceptionIsHiddenByDefault() { public void usernameNotFoundExceptionIsHiddenByDefault() {
final LdapAuthenticator authenticator = jmock.mock(LdapAuthenticator.class); final LdapAuthenticator authenticator = jmock.mock(LdapAuthenticator.class);
final UsernamePasswordAuthenticationToken joe = new UsernamePasswordAuthenticationToken("joe", "password"); final UsernamePasswordAuthenticationToken joe = new UsernamePasswordAuthenticationToken("joe", "password");
@ -98,14 +97,7 @@ public class LdapAuthenticationProviderTests {
}}); }});
LdapAuthenticationProvider provider = new LdapAuthenticationProvider(authenticator); LdapAuthenticationProvider provider = new LdapAuthenticationProvider(authenticator);
try { provider.authenticate(joe);
provider.authenticate(joe);
fail();
} catch (BadCredentialsException expected) {
if (expected instanceof UsernameNotFoundException) {
fail("Exception should have been hidden");
}
}
} }
@Test(expected=UsernameNotFoundException.class) @Test(expected=UsernameNotFoundException.class)

View File

@ -26,6 +26,7 @@ import org.springframework.security.util.ThrowableAnalyzer;
import org.springframework.security.util.ThrowableCauseExtractor; import org.springframework.security.util.ThrowableCauseExtractor;
import org.springframework.security.web.savedrequest.SavedRequest; import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.NestedRuntimeException;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -102,14 +103,17 @@ public class ExceptionTranslationFilter extends SpringSecurityFilter implements
} }
catch (Exception ex) { catch (Exception ex) {
// Try to extract a SpringSecurityException from the stacktrace // Try to extract a SpringSecurityException from the stacktrace
Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(ex); Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex);
SpringSecurityException ase = (SpringSecurityException) NestedRuntimeException ase = (NestedRuntimeException)
this.throwableAnalyzer.getFirstThrowableOfType(SpringSecurityException.class, causeChain); throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, causeChain);
if (ase == null) {
ase = (NestedRuntimeException)throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
}
if (ase != null) { if (ase != null) {
handleException(request, response, chain, ase); handleException(request, response, chain, ase);
} } else {
else {
// Rethrow ServletExceptions and RuntimeExceptions as-is // Rethrow ServletExceptions and RuntimeExceptions as-is
if (ex instanceof ServletException) { if (ex instanceof ServletException) {
throw (ServletException) ex; throw (ServletException) ex;
@ -137,7 +141,7 @@ public class ExceptionTranslationFilter extends SpringSecurityFilter implements
} }
private void handleException(HttpServletRequest request, HttpServletResponse response, FilterChain chain, private void handleException(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
SpringSecurityException exception) throws IOException, ServletException { NestedRuntimeException exception) throws IOException, ServletException {
if (exception instanceof AuthenticationException) { if (exception instanceof AuthenticationException) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Authentication exception occurred; redirecting to authentication entry point", exception); logger.debug("Authentication exception occurred; redirecting to authentication entry point", exception);