@ -15,12 +15,6 @@
@@ -15,12 +15,6 @@
package net.sf.acegisecurity.providers ;
import java.lang.reflect.Constructor ;
import java.lang.reflect.InvocationTargetException ;
import java.util.Iterator ;
import java.util.List ;
import java.util.Properties ;
import net.sf.acegisecurity.AbstractAuthenticationManager ;
import net.sf.acegisecurity.AccountExpiredException ;
import net.sf.acegisecurity.Authentication ;
@ -48,11 +42,21 @@ import net.sf.acegisecurity.providers.cas.ProxyUntrustedException;
@@ -48,11 +42,21 @@ import net.sf.acegisecurity.providers.cas.ProxyUntrustedException;
import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;
import org.springframework.beans.factory.InitializingBean ;
import org.springframework.context.ApplicationEventPublisher ;
import org.springframework.context.ApplicationEventPublisherAware ;
import org.springframework.util.Assert ;
import java.lang.reflect.Constructor ;
import java.lang.reflect.InvocationTargetException ;
import java.util.Iterator ;
import java.util.List ;
import java.util.Properties ;
/ * *
* Iterates an { @link Authentication } request through a list of { @link
@ -76,17 +80,22 @@ import org.springframework.util.Assert;
@@ -76,17 +80,22 @@ import org.springframework.util.Assert;
* < code > ProviderNotFoundException < / code > .
* < / p >
*
* < p > If a valid < code > Authentication < / code > is returned by an < code > AuthenticationProvider < / code > ,
* the < code > ProviderManager < / code > will publish an
* { @link net . sf . acegisecurity . event . authentication . AuthenticationSuccessEvent } . If an
* < code > AuthenticationException < / code > is detected , the final < code > AuthenticationException < / code > thrown
* will be used to publish an appropriate failure event . By default < code > ProviderManager < / code >
* maps common exceptions to events , but this can be fine - tuned by providing a new
* < code > exceptionMappings < / code > < code > java . util . Properties < / code > object . In the
* properties object , each of the keys represent the fully qualified classname of
* the exception , and each of the values represent the name of an event class which subclasses
* { @link net . sf . acegisecurity . event . authentication . AbstractAuthenticationFailureEvent } and
* provides its constructor .
* < p >
* If a valid < code > Authentication < / code > is returned by an
* < code > AuthenticationProvider < / code > , the < code > ProviderManager < / code > will
* publish an { @link
* net . sf . acegisecurity . event . authentication . AuthenticationSuccessEvent } . If
* an < code > AuthenticationException < / code > is detected , the final
* < code > AuthenticationException < / code > thrown will be used to publish an
* appropriate failure event . By default < code > ProviderManager < / code > maps
* common exceptions to events , but this can be fine - tuned by providing a new
* < code > exceptionMappings < / code > < code > java . util . Properties < / code > object . In
* the properties object , each of the keys represent the fully qualified
* classname of the exception , and each of the values represent the name of an
* event class which subclasses { @link
* net . sf . acegisecurity . event . authentication . AbstractAuthenticationFailureEvent }
* and provides its constructor .
* < / p >
*
* @author Ben Alex
* @author Wesley Hall
@ -103,13 +112,18 @@ public class ProviderManager extends AbstractAuthenticationManager
@@ -103,13 +112,18 @@ public class ProviderManager extends AbstractAuthenticationManager
//~ Instance fields ========================================================
private ApplicationEventPublisher applicationEventPublisher ;
private ConcurrentSessionController sessionController = new NullConcurrentSessionController ( ) ;
private List providers ;
private Properties exceptionMappings ;
private ApplicationEventPublisher applicationEventPublisher ;
//~ Methods ================================================================
public void setApplicationEventPublisher (
ApplicationEventPublisher applicationEventPublisher ) {
this . applicationEventPublisher = applicationEventPublisher ;
}
/ * *
* Sets the { @link AuthenticationProvider } objects to be used for
* authentication .
@ -169,28 +183,30 @@ public class ProviderManager extends AbstractAuthenticationManager
@@ -169,28 +183,30 @@ public class ProviderManager extends AbstractAuthenticationManager
public void afterPropertiesSet ( ) throws Exception {
checkIfValidList ( this . providers ) ;
if ( exceptionMappings = = null ) {
exceptionMappings = new Properties ( ) ;
exceptionMappings . put ( AccountExpiredException . class . getName ( ) , AuthenticationFailureExpiredEvent . class . getName ( ) ) ;
exceptionMappings . put ( AuthenticationServiceException . class . getName ( ) , AuthenticationFailureServiceExceptionEvent . class . getName ( ) ) ;
exceptionMappings . put ( LockedException . class . getName ( ) , AuthenticationFailureLockedEvent . class . getName ( ) ) ;
exceptionMappings . put ( CredentialsExpiredException . class . getName ( ) , AuthenticationFailureCredentialsExpiredEvent . class . getName ( ) ) ;
exceptionMappings . put ( DisabledException . class . getName ( ) , AuthenticationFailureDisabledEvent . class . getName ( ) ) ;
exceptionMappings . put ( BadCredentialsException . class . getName ( ) , AuthenticationFailureBadCredentialsEvent . class . getName ( ) ) ;
exceptionMappings . put ( ConcurrentLoginException . class . getName ( ) , AuthenticationFailureConcurrentLoginEvent . class . getName ( ) ) ;
exceptionMappings . put ( ProviderNotFoundException . class . getName ( ) , AuthenticationFailureProviderNotFoundEvent . class . getName ( ) ) ;
exceptionMappings . put ( ProxyUntrustedException . class . getName ( ) , AuthenticationFailureProxyUntrustedEvent . class . getName ( ) ) ;
doAddExtraDefaultExceptionMappings ( exceptionMappings ) ;
exceptionMappings = new Properties ( ) ;
exceptionMappings . put ( AccountExpiredException . class . getName ( ) ,
AuthenticationFailureExpiredEvent . class . getName ( ) ) ;
exceptionMappings . put ( AuthenticationServiceException . class . getName ( ) ,
AuthenticationFailureServiceExceptionEvent . class . getName ( ) ) ;
exceptionMappings . put ( LockedException . class . getName ( ) ,
AuthenticationFailureLockedEvent . class . getName ( ) ) ;
exceptionMappings . put ( CredentialsExpiredException . class . getName ( ) ,
AuthenticationFailureCredentialsExpiredEvent . class . getName ( ) ) ;
exceptionMappings . put ( DisabledException . class . getName ( ) ,
AuthenticationFailureDisabledEvent . class . getName ( ) ) ;
exceptionMappings . put ( BadCredentialsException . class . getName ( ) ,
AuthenticationFailureBadCredentialsEvent . class . getName ( ) ) ;
exceptionMappings . put ( ConcurrentLoginException . class . getName ( ) ,
AuthenticationFailureConcurrentLoginEvent . class . getName ( ) ) ;
exceptionMappings . put ( ProviderNotFoundException . class . getName ( ) ,
AuthenticationFailureProviderNotFoundEvent . class . getName ( ) ) ;
exceptionMappings . put ( ProxyUntrustedException . class . getName ( ) ,
AuthenticationFailureProxyUntrustedEvent . class . getName ( ) ) ;
doAddExtraDefaultExceptionMappings ( exceptionMappings ) ;
}
}
/ * *
* Provided so subclasses can add extra exception mappings during startup if no
* exception mappings are injected by the IoC container .
*
* @param exceptionMappings the properties object , which already has entries in it
* /
protected void doAddExtraDefaultExceptionMappings ( Properties exceptionMappings ) { }
/ * *
* Attempts to authenticate the passed { @link Authentication } object .
@ -215,7 +231,6 @@ public class ProviderManager extends AbstractAuthenticationManager
@@ -215,7 +231,6 @@ public class ProviderManager extends AbstractAuthenticationManager
* @return a fully authenticated object including credentials .
*
* @throws AuthenticationException if authentication fails .
* @throws ProviderNotFoundException DOCUMENT ME !
* /
public Authentication doAuthentication ( Authentication authentication )
throws AuthenticationException {
@ -223,8 +238,6 @@ public class ProviderManager extends AbstractAuthenticationManager
@@ -223,8 +238,6 @@ public class ProviderManager extends AbstractAuthenticationManager
Class toTest = authentication . getClass ( ) ;
sessionController . checkAuthenticationAllowed ( authentication ) ;
AuthenticationException lastException = null ;
while ( iter . hasNext ( ) ) {
@ -239,54 +252,69 @@ public class ProviderManager extends AbstractAuthenticationManager
@@ -239,54 +252,69 @@ public class ProviderManager extends AbstractAuthenticationManager
try {
result = provider . authenticate ( authentication ) ;
sessionController . checkAuthenticationAllowed ( result ) ;
} catch ( AuthenticationException ae ) {
lastException = ae ;
}
if ( result ! = null ) {
sessionController . registerSuccessfulAuthentication ( result ) ;
applicationEventPublisher . publishEvent ( new AuthenticationSuccessEvent ( result ) ) ;
applicationEventPublisher . publishEvent ( new AuthenticationSuccessEvent (
result ) ) ;
return result ;
}
}
}
if ( lastException = = null ) {
lastException = new ProviderNotFoundException ( "No authentication provider for " + toTest . getName ( ) ) ;
lastException = new ProviderNotFoundException (
"No authentication provider for " + toTest . getName ( ) ) ;
}
// Publish the event
String className = exceptionMappings . getProperty ( lastException . getClass ( ) . getName ( ) ) ;
// Publish the event
String className = exceptionMappings . getProperty ( lastException . getClass ( )
. getName ( ) ) ;
AbstractAuthenticationEvent event = null ;
if ( className ! = null ) {
try {
Class clazz = getClass ( ) . getClassLoader ( ) . loadClass ( className ) ;
Constructor constructor = clazz . getConstructor ( new Class [ ] { Authentication . class , AuthenticationException . class } ) ;
Object obj = constructor . newInstance ( new Object [ ] { authentication , lastException } ) ;
Assert . isInstanceOf ( AbstractAuthenticationEvent . class , obj , "Must be an AbstractAuthenticationEvent" ) ;
event = ( AbstractAuthenticationEvent ) obj ;
} catch ( ClassNotFoundException ignored ) {
} catch ( NoSuchMetho dException ignored ) {
} catch ( IllegalAccess Exception ignored ) {
} catch ( Instantiation Exception ignored ) {
} catch ( InvocationTarget Exception ignored ) {
}
try {
Class clazz = getClass ( ) . getClassLoader ( ) . loadClass ( className ) ;
Constructor constructor = clazz . getConstructor ( new Class [ ] { Authentication . class , AuthenticationException . class } ) ;
Object obj = constructor . newInstance ( new Object [ ] { authentication , lastException } ) ;
Assert . isInstanceOf ( AbstractAuthenticationEvent . class , obj ,
"Must be an AbstractAuthenticationEvent" ) ;
event = ( AbstractAuthenticationEvent ) obj ;
} catch ( ClassNotFoun dException ignored ) { }
catch ( NoSuchMethod Exception ignored ) { }
catch ( IllegalAccess Exception ignored ) { }
catch ( Instantiation Exception ignored ) { }
catch ( InvocationTargetException ignored ) { }
}
Assert . notNull ( event , "A valid event must be available for the exception " + lastException . getClass ( ) . getName ( ) ) ;
Assert . notNull ( event ,
"A valid event must be available for the exception "
+ lastException . getClass ( ) . getName ( ) ) ;
applicationEventPublisher . publishEvent ( event ) ;
// Throw the exception
throw lastException ;
}
/ * *
* Provided so subclasses can add extra exception mappings during startup
* if no exception mappings are injected by the IoC container .
*
* @param exceptionMappings the properties object , which already has
* entries in it
* /
protected void doAddExtraDefaultExceptionMappings (
Properties exceptionMappings ) { }
private void checkIfValidList ( List listToCheck ) {
if ( ( listToCheck = = null ) | | ( listToCheck . size ( ) = = 0 ) ) {
throw new IllegalArgumentException (
"A list of AuthenticationManagers is required" ) ;
}
}
public void setApplicationEventPublisher ( ApplicationEventPublisher applicationEventPublisher ) {
this . applicationEventPublisher = applicationEventPublisher ;
}
}