SEC-678: Moved extraInformation property to AuthenticationException so ti isn't only available in BadCredentialsException. Added clearExtraInformation flag to AbstractAuthenticationManager to allow the information to be removed if required before rethrowing.

This commit is contained in:
Luke Taylor 2008-02-18 20:18:40 +00:00
parent 1aec2a6d0a
commit 59651f5214
11 changed files with 88 additions and 28 deletions

View File

@ -22,6 +22,10 @@ package org.springframework.security;
* @version $Id$ * @version $Id$
*/ */
public abstract class AbstractAuthenticationManager implements AuthenticationManager { public abstract class AbstractAuthenticationManager implements AuthenticationManager {
//~ Instance fields ================================================================================================
private boolean clearExtraInformation = false;
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
/** /**
@ -42,6 +46,11 @@ public abstract class AbstractAuthenticationManager implements AuthenticationMan
return doAuthentication(authRequest); return doAuthentication(authRequest);
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
e.setAuthentication(authRequest); e.setAuthentication(authRequest);
if (clearExtraInformation) {
e.clearExtraInformation();
}
throw e; throw e;
} }
} }
@ -59,4 +68,15 @@ public abstract class AbstractAuthenticationManager implements AuthenticationMan
* @throws AuthenticationException if authentication fails * @throws AuthenticationException if authentication fails
*/ */
protected abstract Authentication doAuthentication(Authentication authentication) throws AuthenticationException; protected abstract Authentication doAuthentication(Authentication authentication) throws AuthenticationException;
/**
* If set to true, the <tt>extraInformation</tt> set on an <tt>AuthenticationException</tt> will be cleared
* before rethrowing it. This is useful for use with remoting protocols where the information shouldn't
* be serialized to the client. Defaults to 'false'.
*
* @see org.springframework.security.AuthenticationException#getExtraInformation()
*/
public void setClearExtraInformation(boolean clearExtraInformation) {
this.clearExtraInformation = clearExtraInformation;
}
} }

View File

@ -45,4 +45,8 @@ public class AccountExpiredException extends AccountStatusException {
public AccountExpiredException(String msg, Throwable t) { public AccountExpiredException(String msg, Throwable t) {
super(msg, t); super(msg, t);
} }
public AccountExpiredException(String msg, Object extraInformation) {
super(msg, extraInformation);
}
} }

View File

@ -15,4 +15,8 @@ public abstract class AccountStatusException extends AuthenticationException {
public AccountStatusException(String msg, Throwable t) { public AccountStatusException(String msg, Throwable t) {
super(msg, t); super(msg, t);
} }
protected AccountStatusException(String msg, Object extraInformation) {
super(msg, extraInformation);
}
} }

View File

@ -25,12 +25,12 @@ package org.springframework.security;
public abstract class AuthenticationException extends SpringSecurityException { public abstract class AuthenticationException extends SpringSecurityException {
//~ Instance fields ================================================================================================ //~ Instance fields ================================================================================================
/** The authentication that related to this exception (may be <code>null</code>) */
private Authentication authentication; private Authentication authentication;
private Object extraInformation;
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**
* Constructs an <code>AuthenticationException</code> with the specified * Constructs an <code>AuthenticationException</code> with the specified
* message and root cause. * message and root cause.
* *
@ -41,7 +41,7 @@ public abstract class AuthenticationException extends SpringSecurityException {
super(msg, t); super(msg, t);
} }
/** /**
* Constructs an <code>AuthenticationException</code> with the specified * Constructs an <code>AuthenticationException</code> with the specified
* message and no root cause. * message and no root cause.
* *
@ -51,8 +51,16 @@ public abstract class AuthenticationException extends SpringSecurityException {
super(msg); super(msg);
} }
public AuthenticationException(String msg, Object extraInformation) {
super(msg);
this.extraInformation = extraInformation;
}
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
/**
* The authentication request which this exception corresponds to (may be <code>null</code>)
*/
public Authentication getAuthentication() { public Authentication getAuthentication() {
return authentication; return authentication;
} }
@ -60,4 +68,17 @@ public abstract class AuthenticationException extends SpringSecurityException {
void setAuthentication(Authentication authentication) { void setAuthentication(Authentication authentication) {
this.authentication = authentication; this.authentication = authentication;
} }
/**
* Any additional information about the exception. Generally a <code>UserDetails</code> object.
*
* @return extra information or <code>null</code>
*/
public Object getExtraInformation() {
return extraInformation;
}
void clearExtraInformation() {
this.extraInformation = null;
}
} }

View File

@ -23,10 +23,6 @@ package org.springframework.security;
* @version $Id$ * @version $Id$
*/ */
public class BadCredentialsException extends AuthenticationException { public class BadCredentialsException extends AuthenticationException {
//~ Instance fields ================================================================================================
private Object extraInformation;
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**
@ -40,8 +36,7 @@ public class BadCredentialsException extends AuthenticationException {
} }
public BadCredentialsException(String msg, Object extraInformation) { public BadCredentialsException(String msg, Object extraInformation) {
super(msg); super(msg, extraInformation);
this.extraInformation = extraInformation;
} }
/** /**
@ -57,12 +52,4 @@ public class BadCredentialsException extends AuthenticationException {
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
/**
* Any additional information about the exception. Generally a <code>UserDetails</code> object.
*
* @return extra information or <code>null</code>
*/
public Object getExtraInformation() {
return extraInformation;
}
} }

View File

@ -45,4 +45,8 @@ public class CredentialsExpiredException extends AccountStatusException {
public CredentialsExpiredException(String msg, Throwable t) { public CredentialsExpiredException(String msg, Throwable t) {
super(msg, t); super(msg, t);
} }
public CredentialsExpiredException(String msg, Object extraInformation) {
super(msg, extraInformation);
}
} }

View File

@ -44,4 +44,8 @@ public class DisabledException extends AccountStatusException {
public DisabledException(String msg, Throwable t) { public DisabledException(String msg, Throwable t) {
super(msg, t); super(msg, t);
} }
public DisabledException(String msg, Object extraInformation) {
super(msg, extraInformation);
}
} }

View File

@ -44,4 +44,8 @@ public class LockedException extends AccountStatusException {
public LockedException(String msg, Throwable t) { public LockedException(String msg, Throwable t) {
super(msg, t); super(msg, t);
} }
public LockedException(String msg, Object extraInformation) {
super(msg, extraInformation);
}
} }

View File

@ -269,6 +269,12 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
return preAuthenticationChecks; return preAuthenticationChecks;
} }
/**
* Sets the policy will be used to verify the status of the loaded <tt>UserDetails</tt> <em>before</em>
* validation of the credentials takes place.
*
* @param preAuthenticationChecks strategy to be invoked prior to authentication.
*/
public void setPreAuthenticationChecks(UserDetailsChecker preAuthenticationChecks) { public void setPreAuthenticationChecks(UserDetailsChecker preAuthenticationChecks) {
this.preAuthenticationChecks = preAuthenticationChecks; this.preAuthenticationChecks = preAuthenticationChecks;
} }
@ -285,19 +291,18 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
public void check(UserDetails user) { public void check(UserDetails user) {
if (!user.isAccountNonLocked()) { if (!user.isAccountNonLocked()) {
throw new LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked", throw new LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked",
"User account is locked")); "User account is locked"), user);
} }
if (!user.isEnabled()) { if (!user.isEnabled()) {
throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled",
"User is disabled")); "User is disabled"), user);
} }
if (!user.isAccountNonExpired()) { if (!user.isAccountNonExpired()) {
throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired", throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired",
"User account has expired")); "User account has expired"), user);
} }
} }
} }
@ -305,9 +310,9 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
public void check(UserDetails user) { public void check(UserDetails user) {
if (!user.isCredentialsNonExpired()) { if (!user.isCredentialsNonExpired()) {
throw new CredentialsExpiredException(messages.getMessage( throw new CredentialsExpiredException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.credentialsExpired", "User credentials have expired")); "AbstractUserDetailsAuthenticationProvider.credentialsExpired",
"User credentials have expired"), user);
} }
} }
} }
} }

View File

@ -130,10 +130,17 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
return userDetailsService; return userDetailsService;
} }
public boolean isIncludeDetailsObject() { protected boolean isIncludeDetailsObject() {
return includeDetailsObject; return includeDetailsObject;
} }
/**
* Determines whether the UserDetails will be included in the <tt>extraInformation</tt> field of a
* thrown BadCredentialsException. Defaults to true, but can be set to false if the exception will be
* used with a remoting protocol, for example.
*
* @deprecated use {@link org.springframework.security.providers.ProviderManager#setClearExtraInformation(boolean)}
*/
public void setIncludeDetailsObject(boolean includeDetailsObject) { public void setIncludeDetailsObject(boolean includeDetailsObject) {
this.includeDetailsObject = includeDetailsObject; this.includeDetailsObject = includeDetailsObject;
} }

View File

@ -19,21 +19,21 @@ public class AccountStatusUserDetailsChecker implements UserDetailsChecker {
public void check(UserDetails user) { public void check(UserDetails user) {
if (!user.isAccountNonLocked()) { if (!user.isAccountNonLocked()) {
throw new LockedException(messages.getMessage("UserDetailsService.locked", "User account is locked")); throw new LockedException(messages.getMessage("UserDetailsService.locked", "User account is locked"), user);
} }
if (!user.isEnabled()) { if (!user.isEnabled()) {
throw new DisabledException(messages.getMessage("UserDetailsService.disabled", "User is disabled")); throw new DisabledException(messages.getMessage("UserDetailsService.disabled", "User is disabled"), user);
} }
if (!user.isAccountNonExpired()) { if (!user.isAccountNonExpired()) {
throw new AccountExpiredException(messages.getMessage("UserDetailsService.expired", throw new AccountExpiredException(messages.getMessage("UserDetailsService.expired",
"User account has expired")); "User account has expired"), user);
} }
if (!user.isCredentialsNonExpired()) { if (!user.isCredentialsNonExpired()) {
throw new CredentialsExpiredException(messages.getMessage("UserDetailsService.credentialsExpired", throw new CredentialsExpiredException(messages.getMessage("UserDetailsService.credentialsExpired",
"User credentials have expired")); "User credentials have expired"), user);
} }
} }
} }