2
0
Эх сурвалжийг харах

SEC-70: Refactor event publishing.

Ben Alex 20 жил өмнө
parent
commit
b6dbfde55c
48 өөрчлөгдсөн 638 нэмэгдсэн , 999 устгасан
  1. 4 35
      core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationEvent.java
  2. 51 0
      core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationFailureEvent.java
  3. 8 8
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureBadCredentialsEvent.java
  4. 37 0
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureConcurrentLoginEvent.java
  5. 5 5
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureCredentialsExpiredEvent.java
  6. 6 6
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureDisabledEvent.java
  7. 7 7
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureExpiredEvent.java
  8. 7 7
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureLockedEvent.java
  9. 38 0
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProviderNotFoundEvent.java
  10. 9 8
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProxyUntrustedEvent.java
  11. 37 0
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureServiceExceptionEvent.java
  12. 5 7
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSuccessEvent.java
  13. 13 4
      core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSwitchUserEvent.java
  14. 65 0
      core/src/main/java/org/acegisecurity/event/authentication/LoggerListener.java
  15. 1 1
      core/src/main/java/org/acegisecurity/event/authentication/package.html
  16. 4 4
      core/src/main/java/org/acegisecurity/event/authorization/AbstractAuthorizationEvent.java
  17. 3 3
      core/src/main/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEvent.java
  18. 3 3
      core/src/main/java/org/acegisecurity/event/authorization/AuthorizationFailureEvent.java
  19. 3 3
      core/src/main/java/org/acegisecurity/event/authorization/AuthorizedEvent.java
  20. 2 15
      core/src/main/java/org/acegisecurity/event/authorization/LoggerListener.java
  21. 3 3
      core/src/main/java/org/acegisecurity/event/authorization/PublicInvocationEvent.java
  22. 5 0
      core/src/main/java/org/acegisecurity/event/authorization/package.html
  23. 62 58
      core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java
  24. 0 79
      core/src/main/java/org/acegisecurity/intercept/event/AuthenticationFailureEvent.java
  25. 0 5
      core/src/main/java/org/acegisecurity/intercept/event/package.html
  26. 93 10
      core/src/main/java/org/acegisecurity/providers/ProviderManager.java
  27. 8 81
      core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java
  28. 8 70
      core/src/main/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProvider.java
  29. 0 40
      core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureUsernameNotFoundEvent.java
  30. 0 43
      core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureUsernameOrPasswordEvent.java
  31. 0 131
      core/src/main/java/org/acegisecurity/providers/dao/event/LoggerListener.java
  32. 1 2
      core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java
  33. 16 45
      core/src/test/java/org/acegisecurity/event/authentication/AuthenticationEventTests.java
  34. 57 0
      core/src/test/java/org/acegisecurity/event/authentication/LoggerListenerTests.java
  35. 9 9
      core/src/test/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEventTests.java
  36. 16 16
      core/src/test/java/org/acegisecurity/event/authorization/AuthorizationFailureEventTests.java
  37. 8 9
      core/src/test/java/org/acegisecurity/event/authorization/AuthorizedEventTests.java
  38. 0 88
      core/src/test/java/org/acegisecurity/intercept/event/AuthenticationFailureEventTests.java
  39. 31 6
      core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java
  40. 2 50
      core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java
  41. 0 32
      core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java
  42. 0 98
      core/src/test/java/org/acegisecurity/providers/dao/event/LoggerListenerTests.java
  43. 2 2
      core/src/test/resources/org/acegisecurity/applicationContext.xml
  44. 1 1
      core/src/test/resources/org/acegisecurity/intercept/method/aopalliance/applicationContext.xml
  45. 1 1
      core/src/test/resources/org/acegisecurity/intercept/method/applicationContext.xml
  46. 3 0
      doc/xdocs/upgrade/upgrade-080-090.html
  47. 2 2
      samples/contacts-tiger/src/main/webapp/filter/WEB-INF/applicationContext-acegi-security.xml
  48. 2 2
      samples/contacts/src/main/webapp/filter/WEB-INF/applicationContext-acegi-security.xml

+ 4 - 35
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationEvent.java

@@ -13,27 +13,15 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
 
 import org.springframework.context.ApplicationEvent;
 
-import org.springframework.util.Assert;
-
 
 /**
- * Represents a <code>net.sf.acegisecurity.provider.dao</code> application
- * event.
- * 
- * <P>
- * Subclasses exist for different types of authentication events. All
- * authentication events relate to a particular {@link User} and are caused by
- * a particular {@link Authentication} object. This is intended to permit
- * logging of successful and unsuccessful login attempts, and facilitate the
- * locking of accounts.
- * </p>
+ * Represents an application authentication event.
  * 
  * <P>
  * The <code>ApplicationEvent</code>'s <code>source</code> will be the
@@ -43,20 +31,11 @@ import org.springframework.util.Assert;
  * @author Ben Alex
  * @version $Id$
  */
-public abstract class AuthenticationEvent extends ApplicationEvent {
-    //~ Instance fields ========================================================
-
-    private UserDetails user;
-
+public abstract class AbstractAuthenticationEvent extends ApplicationEvent {
     //~ Constructors ===========================================================
 
-    public AuthenticationEvent(Authentication authentication, UserDetails user) {
+    public AbstractAuthenticationEvent(Authentication authentication) {
         super(authentication);
-
-        // No need to check authentication isn't null, as done by super
-        Assert.notNull(user, "User is required");
-
-        this.user = user;
     }
 
     //~ Methods ================================================================
@@ -70,14 +49,4 @@ public abstract class AuthenticationEvent extends ApplicationEvent {
     public Authentication getAuthentication() {
         return (Authentication) super.getSource();
     }
-
-    /**
-     * Getter for the <code>User</code> related to the
-     * <code>Authentication</code> attempt.
-     *
-     * @return the user
-     */
-    public UserDetails getUser() {
-        return user;
-    }
 }

+ 51 - 0
core/src/main/java/org/acegisecurity/event/authentication/AbstractAuthenticationFailureEvent.java

@@ -0,0 +1,51 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.event.authentication;
+
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.AuthenticationException;
+
+import org.springframework.util.Assert;
+
+
+/**
+ * Abstract application event which indicates authentication failure for some
+ * reason.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public abstract class AbstractAuthenticationFailureEvent
+    extends AbstractAuthenticationEvent {
+    //~ Instance fields ========================================================
+
+    private AuthenticationException exception;
+
+    //~ Constructors ===========================================================
+
+    public AbstractAuthenticationFailureEvent(Authentication authentication,
+        AuthenticationException exception) {
+        super(authentication);
+        Assert.notNull(exception, "AuthenticationException is required");
+        this.exception = exception;
+    }
+
+    //~ Methods ================================================================
+
+    public AuthenticationException getException() {
+        return exception;
+    }
+}

+ 8 - 8
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailurePasswordEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureBadCredentialsEvent.java

@@ -13,25 +13,25 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
+import net.sf.acegisecurity.AuthenticationException;
 
 
 /**
  * Application event which indicates authentication failure due to invalid
- * password.
+ * credentials being presented.
  *
  * @author Ben Alex
  * @version $Id$
  */
-public class AuthenticationFailurePasswordEvent
-    extends AuthenticationFailureEvent {
+public class AuthenticationFailureBadCredentialsEvent
+    extends AbstractAuthenticationFailureEvent {
     //~ Constructors ===========================================================
 
-    public AuthenticationFailurePasswordEvent(Authentication authentication,
-        UserDetails user) {
-        super(authentication, user);
+    public AuthenticationFailureBadCredentialsEvent(
+        Authentication authentication, AuthenticationException exception) {
+        super(authentication, exception);
     }
 }

+ 37 - 0
core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureConcurrentLoginEvent.java

@@ -0,0 +1,37 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.event.authentication;
+
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.AuthenticationException;
+
+
+/**
+ * Application event which indicates authentication failure due to the user
+ * attempting to login to too many concurrent sessions.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class AuthenticationFailureConcurrentLoginEvent
+    extends AbstractAuthenticationFailureEvent {
+    //~ Constructors ===========================================================
+
+    public AuthenticationFailureConcurrentLoginEvent(
+        Authentication authentication, AuthenticationException exception) {
+        super(authentication, exception);
+    }
+}

+ 5 - 5
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureCredentialsExpiredEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureCredentialsExpiredEvent.java

@@ -13,10 +13,10 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
+import net.sf.acegisecurity.AuthenticationException;
 
 
 /**
@@ -27,11 +27,11 @@ import net.sf.acegisecurity.UserDetails;
  * @version $Id$
  */
 public class AuthenticationFailureCredentialsExpiredEvent
-    extends AuthenticationFailureEvent {
+    extends AbstractAuthenticationFailureEvent {
     //~ Constructors ===========================================================
 
     public AuthenticationFailureCredentialsExpiredEvent(
-        Authentication authentication, UserDetails user) {
-        super(authentication, user);
+        Authentication authentication, AuthenticationException exception) {
+        super(authentication, exception);
     }
 }

+ 6 - 6
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureDisabledEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureDisabledEvent.java

@@ -13,25 +13,25 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
+import net.sf.acegisecurity.AuthenticationException;
 
 
 /**
  * Application event which indicates authentication failure due to the user's
- * account being locked.
+ * account being disabled.
  *
  * @author Ben Alex
  * @version $Id$
  */
 public class AuthenticationFailureDisabledEvent
-    extends AuthenticationFailureEvent {
+    extends AbstractAuthenticationFailureEvent {
     //~ Constructors ===========================================================
 
     public AuthenticationFailureDisabledEvent(Authentication authentication,
-        UserDetails user) {
-        super(authentication, user);
+        AuthenticationException exception) {
+        super(authentication, exception);
     }
 }

+ 7 - 7
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureAccountExpiredEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureExpiredEvent.java

@@ -13,10 +13,10 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
+import net.sf.acegisecurity.AuthenticationException;
 
 
 /**
@@ -26,12 +26,12 @@ import net.sf.acegisecurity.UserDetails;
  * @author Ben Alex
  * @version $Id$
  */
-public class AuthenticationFailureAccountExpiredEvent
-    extends AuthenticationFailureEvent {
+public class AuthenticationFailureExpiredEvent
+    extends AbstractAuthenticationFailureEvent {
     //~ Constructors ===========================================================
 
-    public AuthenticationFailureAccountExpiredEvent(
-        Authentication authentication, UserDetails user) {
-        super(authentication, user);
+    public AuthenticationFailureExpiredEvent(Authentication authentication,
+        AuthenticationException exception) {
+        super(authentication, exception);
     }
 }

+ 7 - 7
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureAccountLockedEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureLockedEvent.java

@@ -13,10 +13,10 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
+import net.sf.acegisecurity.AuthenticationException;
 
 
 /**
@@ -26,12 +26,12 @@ import net.sf.acegisecurity.UserDetails;
  * @author Ben Alex
  * @version $Id$
  */
-public class AuthenticationFailureAccountLockedEvent
-    extends AuthenticationFailureEvent {
+public class AuthenticationFailureLockedEvent
+    extends AbstractAuthenticationFailureEvent {
     //~ Constructors ===========================================================
 
-    public AuthenticationFailureAccountLockedEvent(
-        Authentication authentication, UserDetails user) {
-        super(authentication, user);
+    public AuthenticationFailureLockedEvent(Authentication authentication,
+        AuthenticationException exception) {
+        super(authentication, exception);
     }
 }

+ 38 - 0
core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProviderNotFoundEvent.java

@@ -0,0 +1,38 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.event.authentication;
+
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.AuthenticationException;
+
+
+/**
+ * Application event which indicates authentication failure due to there being
+ * no registered <code>AuthenticationProvider</code> that can process the
+ * request.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class AuthenticationFailureProviderNotFoundEvent
+    extends AbstractAuthenticationFailureEvent {
+    //~ Constructors ===========================================================
+
+    public AuthenticationFailureProviderNotFoundEvent(
+        Authentication authentication, AuthenticationException exception) {
+        super(authentication, exception);
+    }
+}

+ 9 - 8
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureProxyUntrustedEvent.java

@@ -13,24 +13,25 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
+import net.sf.acegisecurity.AuthenticationException;
 
 
 /**
- * Abstract application event which indicates authentication failure for some
- * reason.
+ * Application event which indicates authentication failure due to the CAS
+ * user's ticket being generated by an untrusted proxy.
  *
  * @author Ben Alex
  * @version $Id$
  */
-public abstract class AuthenticationFailureEvent extends AuthenticationEvent {
+public class AuthenticationFailureProxyUntrustedEvent
+    extends AbstractAuthenticationFailureEvent {
     //~ Constructors ===========================================================
 
-    public AuthenticationFailureEvent(Authentication authentication,
-        UserDetails user) {
-        super(authentication, user);
+    public AuthenticationFailureProxyUntrustedEvent(
+        Authentication authentication, AuthenticationException exception) {
+        super(authentication, exception);
     }
 }

+ 37 - 0
core/src/main/java/org/acegisecurity/event/authentication/AuthenticationFailureServiceExceptionEvent.java

@@ -0,0 +1,37 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.event.authentication;
+
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.AuthenticationException;
+
+
+/**
+ * Application event which indicates authentication failure due to there being
+ * a problem internal to the <code>AuthenticationManager</code>.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class AuthenticationFailureServiceExceptionEvent
+    extends AbstractAuthenticationFailureEvent {
+    //~ Constructors ===========================================================
+
+    public AuthenticationFailureServiceExceptionEvent(
+        Authentication authentication, AuthenticationException exception) {
+        super(authentication, exception);
+    }
+}

+ 5 - 7
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationSuccessEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSuccessEvent.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,10 +13,9 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
 
 
 /**
@@ -25,11 +24,10 @@ import net.sf.acegisecurity.UserDetails;
  * @author Ben Alex
  * @version $Id$
  */
-public class AuthenticationSuccessEvent extends AuthenticationEvent {
+public class AuthenticationSuccessEvent extends AbstractAuthenticationEvent {
     //~ Constructors ===========================================================
 
-    public AuthenticationSuccessEvent(Authentication authentication,
-        UserDetails user) {
-        super(authentication, user);
+    public AuthenticationSuccessEvent(Authentication authentication) {
+        super(authentication);
     }
 }

+ 13 - 4
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationSwitchUserEvent.java → core/src/main/java/org/acegisecurity/event/authentication/AuthenticationSwitchUserEvent.java

@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import net.sf.acegisecurity.Authentication;
 import net.sf.acegisecurity.UserDetails;
@@ -25,19 +25,28 @@ import net.sf.acegisecurity.UserDetails;
  * @author Mark St.Godard
  * @version $Id$
  */
-public class AuthenticationSwitchUserEvent extends AuthenticationEvent {
+public class AuthenticationSwitchUserEvent extends AbstractAuthenticationEvent {
+    //~ Instance fields ========================================================
+
+    private UserDetails targetUser;
+
     //~ Constructors ===========================================================
 
     /**
      * Switch user context event constructor
      *
      * @param authentication The current <code>Authentication</code> object
-     * @param sourceUser The original user
      * @param targetUser The target user
      */
     public AuthenticationSwitchUserEvent(Authentication authentication,
         UserDetails targetUser) {
-        super(authentication, targetUser);
+        super(authentication);
+        this.targetUser = targetUser;
     }
 
+    //~ Methods ================================================================
+
+    public UserDetails getTargetUser() {
+        return targetUser;
+    }
 }

+ 65 - 0
core/src/main/java/org/acegisecurity/event/authentication/LoggerListener.java

@@ -0,0 +1,65 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.event.authentication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+
+import org.springframework.util.ClassUtils;
+
+
+/**
+ * Outputs authentication-related application events to Commons Logging.
+ * 
+ * <P>
+ * All authentication failures are logged at the warning level, whilst
+ * authentication successes are logged at the information level.
+ * </p>
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class LoggerListener implements ApplicationListener {
+    //~ Static fields/initializers =============================================
+
+    private static final Log logger = LogFactory.getLog(LoggerListener.class);
+
+    //~ Methods ================================================================
+
+    public void onApplicationEvent(ApplicationEvent event) {
+        if (event instanceof AbstractAuthenticationEvent) {
+            AbstractAuthenticationEvent authEvent = (AbstractAuthenticationEvent) event;
+
+            if (logger.isWarnEnabled()) {
+                String message = "Authentication event "
+                    + ClassUtils.getShortName(authEvent.getClass()) + ": "
+                    + authEvent.getAuthentication().getName() + "; details: "
+                    + authEvent.getAuthentication().getDetails();
+
+                if (event instanceof AbstractAuthenticationFailureEvent) {
+                    message = message + "; exception: "
+                        + ((AbstractAuthenticationFailureEvent) event).getException()
+                           .getMessage();
+                }
+
+                logger.warn(message);
+            }
+        }
+    }
+}

+ 1 - 1
core/src/main/java/org/acegisecurity/providers/dao/event/package.html → core/src/main/java/org/acegisecurity/event/authentication/package.html

@@ -2,7 +2,7 @@
 <body>
 Enables events to be published to the Spring application context.
 
-<P>The <code>DaoAuthenticationProvider</code> automatically publishes
+<P>The <code>ProviderManager</code> automatically publishes
 events to the application context. These events are received by all
 registered Spring <code>ApplicationListener</code>s.</P>
 </body>

+ 4 - 4
core/src/main/java/org/acegisecurity/intercept/event/SecurityInterceptionEvent.java → core/src/main/java/org/acegisecurity/event/authorization/AbstractAuthorizationEvent.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 import org.springframework.context.ApplicationEvent;
 
@@ -24,7 +24,7 @@ import org.springframework.context.ApplicationEvent;
  * @author Ben Alex
  * @version $Id$
  */
-public abstract class SecurityInterceptionEvent extends ApplicationEvent {
+public abstract class AbstractAuthorizationEvent extends ApplicationEvent {
     //~ Constructors ===========================================================
 
     /**
@@ -32,7 +32,7 @@ public abstract class SecurityInterceptionEvent extends ApplicationEvent {
      *
      * @param secureObject the secure object
      */
-    public SecurityInterceptionEvent(Object secureObject) {
+    public AbstractAuthorizationEvent(Object secureObject) {
         super(secureObject);
     }
 }

+ 3 - 3
core/src/main/java/org/acegisecurity/intercept/event/AuthenticationCredentialsNotFoundEvent.java → core/src/main/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEvent.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 import net.sf.acegisecurity.AuthenticationCredentialsNotFoundException;
 import net.sf.acegisecurity.ConfigAttributeDefinition;
@@ -28,7 +28,7 @@ import net.sf.acegisecurity.ConfigAttributeDefinition;
  * @version $Id$
  */
 public class AuthenticationCredentialsNotFoundEvent
-    extends SecurityInterceptionEvent {
+    extends AbstractAuthorizationEvent {
     //~ Instance fields ========================================================
 
     private AuthenticationCredentialsNotFoundException credentialsNotFoundException;

+ 3 - 3
core/src/main/java/org/acegisecurity/intercept/event/AuthorizationFailureEvent.java → core/src/main/java/org/acegisecurity/event/authorization/AuthorizationFailureEvent.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 import net.sf.acegisecurity.AccessDeniedException;
 import net.sf.acegisecurity.Authentication;
@@ -27,7 +27,7 @@ import net.sf.acegisecurity.ConfigAttributeDefinition;
  * @author Ben Alex
  * @version $Id$
  */
-public class AuthorizationFailureEvent extends SecurityInterceptionEvent {
+public class AuthorizationFailureEvent extends AbstractAuthorizationEvent {
     //~ Instance fields ========================================================
 
     private AccessDeniedException accessDeniedException;

+ 3 - 3
core/src/main/java/org/acegisecurity/intercept/event/AuthorizedEvent.java → core/src/main/java/org/acegisecurity/event/authorization/AuthorizedEvent.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 import net.sf.acegisecurity.Authentication;
 import net.sf.acegisecurity.ConfigAttributeDefinition;
@@ -29,7 +29,7 @@ import net.sf.acegisecurity.ConfigAttributeDefinition;
  * @author Ben Alex
  * @version $Id$
  */
-public class AuthorizedEvent extends SecurityInterceptionEvent {
+public class AuthorizedEvent extends AbstractAuthorizationEvent {
     //~ Instance fields ========================================================
 
     private Authentication authentication;

+ 2 - 15
core/src/main/java/org/acegisecurity/intercept/event/LoggerListener.java → core/src/main/java/org/acegisecurity/event/authorization/LoggerListener.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -54,19 +54,6 @@ public class LoggerListener implements ApplicationListener {
             }
         }
 
-        if (event instanceof AuthenticationFailureEvent) {
-            AuthenticationFailureEvent authEvent = (AuthenticationFailureEvent) event;
-
-            if (logger.isWarnEnabled()) {
-                logger.warn("Security authentication failed due to: "
-                    + authEvent.getAuthenticationException()
-                    + "; for authentication request: "
-                    + authEvent.getAuthentication() + "; secure object: "
-                    + authEvent.getSource() + "; configuration attributes: "
-                    + authEvent.getConfigAttributeDefinition());
-            }
-        }
-
         if (event instanceof AuthorizationFailureEvent) {
             AuthorizationFailureEvent authEvent = (AuthorizationFailureEvent) event;
 

+ 3 - 3
core/src/main/java/org/acegisecurity/intercept/event/PublicInvocationEvent.java → core/src/main/java/org/acegisecurity/event/authorization/PublicInvocationEvent.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 /**
  * Event that is generated whenever a public secure object is invoked.
@@ -32,7 +32,7 @@ package net.sf.acegisecurity.intercept.event;
  * @author Ben Alex
  * @version $Id$
  */
-public class PublicInvocationEvent extends SecurityInterceptionEvent {
+public class PublicInvocationEvent extends AbstractAuthorizationEvent {
     //~ Constructors ===========================================================
 
     /**

+ 5 - 0
core/src/main/java/org/acegisecurity/event/authorization/package.html

@@ -0,0 +1,5 @@
+<html>
+<body>
+Provides support objects for security event interception (ie authorization).
+</body>
+</html>

+ 62 - 58
core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java

@@ -12,6 +12,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package net.sf.acegisecurity.intercept;
 
 import net.sf.acegisecurity.AccessDecisionManager;
@@ -25,11 +26,10 @@ import net.sf.acegisecurity.ConfigAttribute;
 import net.sf.acegisecurity.ConfigAttributeDefinition;
 import net.sf.acegisecurity.RunAsManager;
 import net.sf.acegisecurity.context.SecurityContextHolder;
-import net.sf.acegisecurity.intercept.event.AuthenticationCredentialsNotFoundEvent;
-import net.sf.acegisecurity.intercept.event.AuthenticationFailureEvent;
-import net.sf.acegisecurity.intercept.event.AuthorizationFailureEvent;
-import net.sf.acegisecurity.intercept.event.AuthorizedEvent;
-import net.sf.acegisecurity.intercept.event.PublicInvocationEvent;
+import net.sf.acegisecurity.event.authorization.AuthenticationCredentialsNotFoundEvent;
+import net.sf.acegisecurity.event.authorization.AuthorizationFailureEvent;
+import net.sf.acegisecurity.event.authorization.AuthorizedEvent;
+import net.sf.acegisecurity.event.authorization.PublicInvocationEvent;
 import net.sf.acegisecurity.runas.NullRunAsManager;
 
 import org.apache.commons.logging.Log;
@@ -50,16 +50,16 @@ import java.util.Set;
 
 /**
  * Abstract class that implements security interception for secure objects.
- *
+ * 
  * <P>
  * The <code>AbstractSecurityInterceptor</code> will ensure the proper startup
  * configuration of the security interceptor. It will also implement the
  * proper handling of secure object invocations, being:
- *
+ * 
  * <ol>
  * <li>
- * Obtain the {@link Authentication} object from the
- * {@link SecurityContextHolder}.
+ * Obtain the {@link Authentication} object from the {@link
+ * SecurityContextHolder}.
  * </li>
  * <li>
  * Determine if the request relates to a secured or public invocation by
@@ -69,7 +69,7 @@ import java.util.Set;
  * <li>
  * For an invocation that is secured (there is a
  * <code>ConfigAttributeDefinition</code> for the secure object invocation):
- *
+ * 
  * <ol type="a">
  * <li>
  * If either the {@link net.sf.acegisecurity.Authentication#isAuthenticated()}
@@ -108,12 +108,12 @@ import java.util.Set;
  * caller.
  * </li>
  * </ol>
- *
+ * 
  * </li>
  * <li>
  * For an invocation that is public (there is no
  * <code>ConfigAttributeDefinition</code> for the secure object invocation):
- *
+ * 
  * <ol type="a">
  * <li>
  * As described above, the concrete subclass will be returned an
@@ -124,7 +124,7 @@ import java.util.Set;
  * Object)} is called.
  * </li>
  * </ol>
- *
+ * 
  * </li>
  * <li>
  * Control again returns to the concrete subclass, along with the
@@ -139,7 +139,12 @@ import java.util.Set;
  */
 public abstract class AbstractSecurityInterceptor implements InitializingBean,
     ApplicationContextAware {
+    //~ Static fields/initializers =============================================
+
     protected static final Log logger = LogFactory.getLog(AbstractSecurityInterceptor.class);
+
+    //~ Instance fields ========================================================
+
     private AccessDecisionManager accessDecisionManager;
     private AfterInvocationManager afterInvocationManager;
     private ApplicationContext context;
@@ -148,6 +153,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
     private boolean alwaysReauthenticate = false;
     private boolean validateConfigAttributes = true;
 
+    //~ Methods ================================================================
+
     public void setAfterInvocationManager(
         AfterInvocationManager afterInvocationManager) {
         this.afterInvocationManager = afterInvocationManager;
@@ -245,27 +252,27 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
 
         if (!this.obtainObjectDefinitionSource().supports(getSecureObjectClass())) {
             throw new IllegalArgumentException(
-                "ObjectDefinitionSource does not support secure object class: " +
-                getSecureObjectClass());
+                "ObjectDefinitionSource does not support secure object class: "
+                + getSecureObjectClass());
         }
 
         if (!this.runAsManager.supports(getSecureObjectClass())) {
             throw new IllegalArgumentException(
-                "RunAsManager does not support secure object class: " +
-                getSecureObjectClass());
+                "RunAsManager does not support secure object class: "
+                + getSecureObjectClass());
         }
 
         if (!this.accessDecisionManager.supports(getSecureObjectClass())) {
             throw new IllegalArgumentException(
-                "AccessDecisionManager does not support secure object class: " +
-                getSecureObjectClass());
+                "AccessDecisionManager does not support secure object class: "
+                + getSecureObjectClass());
         }
 
-        if ((this.afterInvocationManager != null) &&
-                !this.afterInvocationManager.supports(getSecureObjectClass())) {
+        if ((this.afterInvocationManager != null)
+            && !this.afterInvocationManager.supports(getSecureObjectClass())) {
             throw new IllegalArgumentException(
-                "AfterInvocationManager does not support secure object class: " +
-                getSecureObjectClass());
+                "AfterInvocationManager does not support secure object class: "
+                + getSecureObjectClass());
         }
 
         if (this.validateConfigAttributes) {
@@ -281,16 +288,18 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
                 Set set = new HashSet();
 
                 while (iter.hasNext()) {
-                    ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter.next();
+                    ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter
+                        .next();
                     Iterator attributes = def.getConfigAttributes();
 
                     while (attributes.hasNext()) {
-                        ConfigAttribute attr = (ConfigAttribute) attributes.next();
+                        ConfigAttribute attr = (ConfigAttribute) attributes
+                            .next();
 
-                        if (!this.runAsManager.supports(attr) &&
-                                !this.accessDecisionManager.supports(attr) &&
-                                ((this.afterInvocationManager == null) ||
-                                !this.afterInvocationManager.supports(attr))) {
+                        if (!this.runAsManager.supports(attr)
+                            && !this.accessDecisionManager.supports(attr)
+                            && ((this.afterInvocationManager == null)
+                            || !this.afterInvocationManager.supports(attr))) {
                             set.add(attr);
                         }
                     }
@@ -302,8 +311,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
                     }
                 } else {
                     throw new IllegalArgumentException(
-                        "Unsupported configuration attributes: " +
-                        set.toString());
+                        "Unsupported configuration attributes: "
+                        + set.toString());
                 }
             }
         }
@@ -330,16 +339,18 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
 
         if (token.isContextHolderRefreshRequired()) {
             if (logger.isDebugEnabled()) {
-                logger.debug("Reverting to original Authentication: " +
-                    token.getAuthentication().toString());
+                logger.debug("Reverting to original Authentication: "
+                    + token.getAuthentication().toString());
             }
 
-            SecurityContextHolder.getContext().setAuthentication(token.getAuthentication());
+            SecurityContextHolder.getContext().setAuthentication(token
+                .getAuthentication());
         }
 
         if (afterInvocationManager != null) {
-            returnedObject = afterInvocationManager.decide(token.getAuthentication(),
-                    token.getSecureObject(), token.getAttr(), returnedObject);
+            returnedObject = afterInvocationManager.decide(token
+                    .getAuthentication(), token.getSecureObject(),
+                    token.getAttr(), returnedObject);
         }
 
         return returnedObject;
@@ -348,18 +359,18 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
     protected InterceptorStatusToken beforeInvocation(Object object) {
         Assert.notNull(object, "Object was null");
         Assert.isTrue(getSecureObjectClass().isAssignableFrom(object.getClass()),
-            "Security invocation attempted for object " +
-            object.getClass().getName() +
-            " but AbstractSecurityInterceptor only configured to support secure objects of type: " +
-            getSecureObjectClass());
+            "Security invocation attempted for object "
+            + object.getClass().getName()
+            + " but AbstractSecurityInterceptor only configured to support secure objects of type: "
+            + getSecureObjectClass());
 
         ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource()
                                              .getAttributes(object);
 
         if (attr != null) {
             if (logger.isDebugEnabled()) {
-                logger.debug("Secure object: " + object.toString() +
-                    "; ConfigAttributes: " + attr.toString());
+                logger.debug("Secure object: " + object.toString()
+                    + "; ConfigAttributes: " + attr.toString());
             }
 
             // We check for just the property we're interested in (we do
@@ -373,26 +384,19 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
             Authentication authenticated;
 
             if (!SecurityContextHolder.getContext().getAuthentication()
-                                          .isAuthenticated() ||
-                    alwaysReauthenticate) {
+                                      .isAuthenticated()
+                || alwaysReauthenticate) {
                 try {
                     authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext()
                                                                                                  .getAuthentication());
                 } catch (AuthenticationException authenticationException) {
-                    AuthenticationFailureEvent event = new AuthenticationFailureEvent(object,
-                            attr,
-                            SecurityContextHolder.getContext()
-                                                 .getAuthentication(),
-                            authenticationException);
-                    this.context.publishEvent(event);
-
                     throw authenticationException;
                 }
 
                 // We don't authenticated.setAuthentication(true), because each provider should do that
                 if (logger.isDebugEnabled()) {
-                    logger.debug("Successfully Authenticated: " +
-                        authenticated.toString());
+                    logger.debug("Successfully Authenticated: "
+                        + authenticated.toString());
                 }
 
                 SecurityContextHolder.getContext().setAuthentication(authenticated);
@@ -401,8 +405,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
                                                      .getAuthentication();
 
                 if (logger.isDebugEnabled()) {
-                    logger.debug("Previously Authenticated: " +
-                        authenticated.toString());
+                    logger.debug("Previously Authenticated: "
+                        + authenticated.toString());
                 }
             }
 
@@ -439,8 +443,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
                     object); // no further work post-invocation
             } else {
                 if (logger.isDebugEnabled()) {
-                    logger.debug("Switching to RunAs Authentication: " +
-                        runAs.toString());
+                    logger.debug("Switching to RunAs Authentication: "
+                        + runAs.toString());
                 }
 
                 SecurityContextHolder.getContext().setAuthentication(runAs);
@@ -462,7 +466,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
     /**
      * Helper method which generates an exception containing the passed reason,
      * and publishes an event to the application context.
-     *
+     * 
      * <P>
      * Always throws an exception.
      * </p>

+ 0 - 79
core/src/main/java/org/acegisecurity/intercept/event/AuthenticationFailureEvent.java

@@ -1,79 +0,0 @@
-/* Copyright 2004 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.sf.acegisecurity.intercept.event;
-
-import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.AuthenticationException;
-import net.sf.acegisecurity.ConfigAttributeDefinition;
-
-
-/**
- * Indicates a secure object invocation failed because the principal could not
- * be authenticated.
- *
- * @author Ben Alex
- * @version $Id$
- */
-public class AuthenticationFailureEvent extends SecurityInterceptionEvent {
-    //~ Instance fields ========================================================
-
-    private Authentication authentication;
-    private AuthenticationException authenticationException;
-    private ConfigAttributeDefinition configAttributeDefinition;
-
-    //~ Constructors ===========================================================
-
-    /**
-     * Construct the event.
-     *
-     * @param secureObject the secure object
-     * @param configAttribs that apply to the secure object
-     * @param authentication that was found on the <code>ContextHolder</code>
-     * @param authenticationException that was returned by the
-     *        <code>AuthenticationManager</code>
-     *
-     * @throws IllegalArgumentException DOCUMENT ME!
-     */
-    public AuthenticationFailureEvent(Object secureObject,
-        ConfigAttributeDefinition configAttribs, Authentication authentication,
-        AuthenticationException authenticationException) {
-        super(secureObject);
-
-        if ((configAttribs == null) || (authentication == null)
-            || (authenticationException == null)) {
-            throw new IllegalArgumentException(
-                "All parameters are required and cannot be null");
-        }
-
-        this.configAttributeDefinition = configAttribs;
-        this.authentication = authentication;
-        this.authenticationException = authenticationException;
-    }
-
-    //~ Methods ================================================================
-
-    public Authentication getAuthentication() {
-        return authentication;
-    }
-
-    public AuthenticationException getAuthenticationException() {
-        return authenticationException;
-    }
-
-    public ConfigAttributeDefinition getConfigAttributeDefinition() {
-        return configAttributeDefinition;
-    }
-}

+ 0 - 5
core/src/main/java/org/acegisecurity/intercept/event/package.html

@@ -1,5 +0,0 @@
-<html>
-<body>
-Provides support objects for security event interception.
-</body>
-</html>

+ 93 - 10
core/src/main/java/org/acegisecurity/providers/ProviderManager.java

@@ -15,19 +15,43 @@
 
 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;
 import net.sf.acegisecurity.AuthenticationException;
+import net.sf.acegisecurity.AuthenticationServiceException;
+import net.sf.acegisecurity.BadCredentialsException;
+import net.sf.acegisecurity.CredentialsExpiredException;
+import net.sf.acegisecurity.DisabledException;
+import net.sf.acegisecurity.LockedException;
+import net.sf.acegisecurity.concurrent.ConcurrentLoginException;
 import net.sf.acegisecurity.concurrent.ConcurrentSessionController;
 import net.sf.acegisecurity.concurrent.NullConcurrentSessionController;
+import net.sf.acegisecurity.event.authentication.AbstractAuthenticationEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureBadCredentialsEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureConcurrentLoginEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureCredentialsExpiredEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureDisabledEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureExpiredEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureLockedEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureProviderNotFoundEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureProxyUntrustedEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationFailureServiceExceptionEvent;
+import net.sf.acegisecurity.event.authentication.AuthenticationSuccessEvent;
+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 java.util.Iterator;
-import java.util.List;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
+import org.springframework.util.Assert;
 
 
 /**
@@ -51,6 +75,18 @@ import java.util.List;
  * <code>Authentication</code>, the <code>ProviderManager</code> will throw a
  * <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.
  *
  * @author Ben Alex
  * @author Wesley Hall
@@ -60,7 +96,7 @@ import java.util.List;
  * @see ConcurrentSessionController
  */
 public class ProviderManager extends AbstractAuthenticationManager
-    implements InitializingBean {
+    implements InitializingBean, ApplicationEventPublisherAware {
     //~ Static fields/initializers =============================================
 
     private static final Log logger = LogFactory.getLog(ProviderManager.class);
@@ -69,6 +105,8 @@ public class ProviderManager extends AbstractAuthenticationManager
 
     private ConcurrentSessionController sessionController = new NullConcurrentSessionController();
     private List providers;
+    private Properties exceptionMappings;
+    private ApplicationEventPublisher applicationEventPublisher;
 
     //~ Methods ================================================================
 
@@ -131,7 +169,28 @@ 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);
+        }
     }
+    
+    /**
+     * 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.
@@ -186,18 +245,38 @@ public class ProviderManager extends AbstractAuthenticationManager
 
                 if (result != null) {
                     sessionController.registerSuccessfulAuthentication(result);
-
+                    applicationEventPublisher.publishEvent(new AuthenticationSuccessEvent(result));
                     return result;
                 }
             }
         }
 
-        if (lastException != null) {
-            throw lastException;
+        if (lastException == null) {
+        	lastException = new ProviderNotFoundException("No authentication provider for " + toTest.getName());
         }
 
-        throw new ProviderNotFoundException("No authentication provider for "
-            + toTest.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 (NoSuchMethodException ignored) {
+        	} catch (IllegalAccessException ignored) {
+        	} catch (InstantiationException ignored) {
+        	} catch (InvocationTargetException ignored) {
+        	}
+        }
+        Assert.notNull(event, "A valid event must be available for the exception " + lastException.getClass().getName());
+        applicationEventPublisher.publishEvent(event);
+        
+        // Throw the exception
+        throw lastException;
     }
 
     private void checkIfValidList(List listToCheck) {
@@ -206,4 +285,8 @@ public class ProviderManager extends AbstractAuthenticationManager
                 "A list of AuthenticationManagers is required");
         }
     }
+
+	public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
+		this.applicationEventPublisher = applicationEventPublisher;		
+	}
 }

+ 8 - 81
core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java

@@ -22,29 +22,18 @@ import net.sf.acegisecurity.AuthenticationServiceException;
 import net.sf.acegisecurity.BadCredentialsException;
 import net.sf.acegisecurity.CredentialsExpiredException;
 import net.sf.acegisecurity.DisabledException;
-import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.LockedException;
 import net.sf.acegisecurity.UserDetails;
 import net.sf.acegisecurity.providers.AuthenticationProvider;
 import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 import net.sf.acegisecurity.providers.dao.cache.NullUserCache;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureAccountExpiredEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureAccountLockedEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureCredentialsExpiredEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureDisabledEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailurePasswordEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureUsernameNotFoundEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationSuccessEvent;
 import net.sf.acegisecurity.providers.encoding.PasswordEncoder;
 import net.sf.acegisecurity.providers.encoding.PlaintextPasswordEncoder;
 
-import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.InitializingBean;
 
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-
 import org.springframework.dao.DataAccessException;
+
 import org.springframework.util.Assert;
 
 
@@ -83,23 +72,14 @@ import org.springframework.util.Assert;
  * incorrect password, the {@link AuthenticationDao} will be queried to
  * confirm the most up-to-date password was used for comparison.
  * </p>
- * 
- * <P>
- * If an application context is detected (which is automatically the case when
- * the bean is started within a Spring container), application events will be
- * published to the context. See {@link
- * net.sf.acegisecurity.providers.dao.event.AuthenticationEvent} for further
- * information.
- * </p>
  *
  * @author Ben Alex
  * @version $Id$
  */
 public class DaoAuthenticationProvider implements AuthenticationProvider,
-    InitializingBean, ApplicationContextAware {
+    InitializingBean {
     //~ Instance fields ========================================================
 
-    private ApplicationContext context;
     private AuthenticationDao authenticationDao;
     private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder();
     private SaltSource saltSource;
@@ -109,11 +89,6 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
 
     //~ Methods ================================================================
 
-    public void setApplicationContext(ApplicationContext applicationContext)
-        throws BeansException {
-        this.context = applicationContext;
-    }
-
     public void setAuthenticationDao(AuthenticationDao authenticationDao) {
         this.authenticationDao = authenticationDao;
     }
@@ -122,10 +97,6 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
         return authenticationDao;
     }
 
-    public ApplicationContext getContext() {
-        return context;
-    }
-
     public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
         this.forcePrincipalAsString = forcePrincipalAsString;
     }
@@ -140,7 +111,7 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
      * password is incorrect. Setting this property to <code>false</code> will
      * cause <code>UsernameNotFoundException</code>s to be thrown instead for
      * the former. Note this is considered less secure than throwing
-     * <code>BadCredentialsException</code> for both events.
+     * <code>BadCredentialsException</code> for both exceptions.
      *
      * @param hideUserNotFoundExceptions set to <code>false</code> if you wish
      *        <code>UsernameNotFoundException</code>s to be thrown instead of
@@ -197,7 +168,8 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
     }
 
     public void afterPropertiesSet() throws Exception {
-        Assert.notNull(this.authenticationDao, "An Authentication DAO must be set");
+        Assert.notNull(this.authenticationDao,
+            "An Authentication DAO must be set");
         Assert.notNull(this.userCache, "A user cache must be set");
     }
 
@@ -220,29 +192,10 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
 
         if (user == null) {
             cacheWasUsed = false;
-
-            try {
-                user = getUserFromBackend(username);
-            } catch (BadCredentialsException ex) {
-                if (this.context != null) {
-                    context.publishEvent(new AuthenticationFailureUsernameNotFoundEvent(
-                            authentication,
-                            new User("".equals(username)
-                                ? "EMPTY_STRING_PROVIDED" : username, "*****",
-                                false, false, false, false,
-                                new GrantedAuthority[0])));
-                }
-
-                throw ex;
-            }
+            user = getUserFromBackend(username);
         }
 
         if (!user.isAccountNonLocked()) {
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationFailureAccountLockedEvent(
-                        authentication, user));
-            }
-
             throw new LockedException("User account is locked");
         }
 
@@ -254,52 +207,26 @@ public class DaoAuthenticationProvider implements AuthenticationProvider,
             }
 
             if (!isPasswordCorrect(authentication, user)) {
-                if (this.context != null) {
-                    context.publishEvent(new AuthenticationFailurePasswordEvent(
-                            authentication, user));
-                }
-
                 throw new BadCredentialsException("Bad credentials presented");
             }
         }
 
         if (!user.isEnabled()) {
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationFailureDisabledEvent(
-                        authentication, user));
-            }
-
             throw new DisabledException("User is disabled");
         }
 
         if (!user.isAccountNonExpired()) {
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationFailureAccountExpiredEvent(
-                        authentication, user));
-            }
-
             throw new AccountExpiredException("User account has expired");
         }
 
-		if (!user.isCredentialsNonExpired()) {
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationFailureCredentialsExpiredEvent(
-                        authentication, user));
-            }
-
+        if (!user.isCredentialsNonExpired()) {
             throw new CredentialsExpiredException(
                 "User credentials have expired");
-        }        
+        }
 
         if (!cacheWasUsed) {
             // Put into cache
             this.userCache.putUserInCache(user);
-
-            // As this appears to be an initial login, publish the event
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationSuccessEvent(
-                        authentication, user));
-            }
         }
 
         Object principalToReturn = user;

+ 8 - 70
core/src/main/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProvider.java

@@ -19,29 +19,18 @@ import net.sf.acegisecurity.AccountExpiredException;
 import net.sf.acegisecurity.Authentication;
 import net.sf.acegisecurity.AuthenticationException;
 import net.sf.acegisecurity.AuthenticationServiceException;
-import net.sf.acegisecurity.BadCredentialsException;
 import net.sf.acegisecurity.CredentialsExpiredException;
 import net.sf.acegisecurity.DisabledException;
-import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.LockedException;
 import net.sf.acegisecurity.UserDetails;
 import net.sf.acegisecurity.providers.AuthenticationProvider;
 import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 import net.sf.acegisecurity.providers.dao.cache.NullUserCache;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureAccountExpiredEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureAccountLockedEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureCredentialsExpiredEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureDisabledEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationFailureUsernameOrPasswordEvent;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationSuccessEvent;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.InitializingBean;
 
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
+import org.springframework.beans.factory.InitializingBean;
 
 import org.springframework.dao.DataAccessException;
+
 import org.springframework.util.Assert;
 
 
@@ -90,32 +79,22 @@ import org.springframework.util.Assert;
  * If an application context is detected (which is automatically the case when
  * the bean is started within a Spring container), application events will be
  * published to the context. See {@link
- * net.sf.acegisecurity.providers.dao.event.AuthenticationEvent} for further
- * information.
+ * net.sf.acegisecurity.event.authentication.AbstractAuthenticationEvent} for
+ * further information.
  * </p>
  *
  * @author Karel Miarka
  */
 public class PasswordDaoAuthenticationProvider implements AuthenticationProvider,
-    InitializingBean, ApplicationContextAware {
+    InitializingBean {
     //~ Instance fields ========================================================
 
-    private ApplicationContext context;
     private PasswordAuthenticationDao authenticationDao;
     private UserCache userCache = new NullUserCache();
     private boolean forcePrincipalAsString = false;
 
     //~ Methods ================================================================
 
-    public void setApplicationContext(ApplicationContext applicationContext)
-        throws BeansException {
-        this.context = applicationContext;
-    }
-
-    public ApplicationContext getContext() {
-        return context;
-    }
-
     public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
         this.forcePrincipalAsString = forcePrincipalAsString;
     }
@@ -142,7 +121,8 @@ public class PasswordDaoAuthenticationProvider implements AuthenticationProvider
     }
 
     public void afterPropertiesSet() throws Exception {
-        Assert.notNull(this.authenticationDao, "A Password authentication DAO must be set");
+        Assert.notNull(this.authenticationDao,
+            "A Password authentication DAO must be set");
         Assert.notNull(this.userCache, "A user cache must be set");
     }
 
@@ -169,58 +149,22 @@ public class PasswordDaoAuthenticationProvider implements AuthenticationProvider
 
         if (user == null) {
             cacheWasUsed = false;
-
-            try {
-                user = getUserFromBackend(username, password);
-            } catch (BadCredentialsException ex) {
-                if (this.context != null) {
-                    if ((username == null) || "".equals(username)) {
-                        username = "NONE_PROVIDED";
-                    }
-
-                    context.publishEvent(new AuthenticationFailureUsernameOrPasswordEvent(
-                            authentication,
-                            new User(username, "*****", false, false, false,
-                                false, new GrantedAuthority[0])));
-                }
-
-                throw ex;
-            }
+            user = getUserFromBackend(username, password);
         }
 
         if (!user.isEnabled()) {
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationFailureDisabledEvent(
-                        authentication, user));
-            }
-
             throw new DisabledException("User is disabled");
         }
 
         if (!user.isAccountNonExpired()) {
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationFailureAccountExpiredEvent(
-                        authentication, user));
-            }
-
             throw new AccountExpiredException("User account has expired");
         }
 
         if (!user.isAccountNonLocked()) {
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationFailureAccountLockedEvent(
-                        authentication, user));
-            }
-
             throw new LockedException("User account is locked");
         }
 
         if (!user.isCredentialsNonExpired()) {
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationFailureCredentialsExpiredEvent(
-                        authentication, user));
-            }
-
             throw new CredentialsExpiredException(
                 "User credentials have expired");
         }
@@ -228,12 +172,6 @@ public class PasswordDaoAuthenticationProvider implements AuthenticationProvider
         if (!cacheWasUsed) {
             // Put into cache
             this.userCache.putUserInCache(user);
-
-            // As this appears to be an initial login, publish the event
-            if (this.context != null) {
-                context.publishEvent(new AuthenticationSuccessEvent(
-                        authentication, user));
-            }
         }
 
         Object principalToReturn = user;

+ 0 - 40
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureUsernameNotFoundEvent.java

@@ -1,40 +0,0 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.sf.acegisecurity.providers.dao.event;
-
-import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
-
-
-/**
- * Application event which indicates authentication failure due to nonexistent
- * username. <code>AuthenticationFailureUsernameNotFoundEvent.getUser()</code>
- * returns an instance of <code>User</code>, where the username is filled by
- * the <code>String</code> provided at login attempt. The other properties are
- * set to non-<code>null</code> values without any meaning.
- *
- * @author Karel Miarka
- */
-public class AuthenticationFailureUsernameNotFoundEvent
-    extends AuthenticationFailureEvent {
-    //~ Constructors ===========================================================
-
-    //  ~ Constructors ===========================================================
-    public AuthenticationFailureUsernameNotFoundEvent(
-        Authentication authentication, UserDetails user) {
-        super(authentication, user);
-    }
-}

+ 0 - 43
core/src/main/java/org/acegisecurity/providers/dao/event/AuthenticationFailureUsernameOrPasswordEvent.java

@@ -1,43 +0,0 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.sf.acegisecurity.providers.dao.event;
-
-import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.UserDetails;
-
-
-/**
- * Application event which indicates authentication failure due to invalid
- * username or password.
- * 
- * <P>
- * <code>AuthenticationFailureUsernameOrPasswordEvent.getUser()</code> returns
- * an instance of <code>User</code>, where the username is filled by the
- * <code>String</code> provided at login attempt. The other properties are set
- * to non-<code>null</code> values without any meaning.
- * </p>
- *
- * @author Karel Miarka
- */
-public class AuthenticationFailureUsernameOrPasswordEvent
-    extends AuthenticationFailureEvent {
-    //~ Constructors ===========================================================
-
-    public AuthenticationFailureUsernameOrPasswordEvent(
-        Authentication authentication, UserDetails user) {
-        super(authentication, user);
-    }
-}

+ 0 - 131
core/src/main/java/org/acegisecurity/providers/dao/event/LoggerListener.java

@@ -1,131 +0,0 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.sf.acegisecurity.providers.dao.event;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.context.ApplicationEvent;
-import org.springframework.context.ApplicationListener;
-
-
-/**
- * Outputs authentication-related application events to Commons Logging.
- * 
- * <P>
- * All authentication failures are logged at the warning level, whilst
- * authentication successes are logged at the information level.
- * </p>
- *
- * @author Ben Alex
- * @version $Id$
- */
-public class LoggerListener implements ApplicationListener {
-    //~ Static fields/initializers =============================================
-
-    private static final Log logger = LogFactory.getLog(LoggerListener.class);
-
-    //~ Methods ================================================================
-
-    public void onApplicationEvent(ApplicationEvent event) {
-        if (event instanceof AuthenticationFailurePasswordEvent) {
-            AuthenticationFailurePasswordEvent authEvent = (AuthenticationFailurePasswordEvent) event;
-
-            if (logger.isWarnEnabled()) {
-                logger.warn(
-                    "Authentication failed due to incorrect password for user: "
-                    + authEvent.getUser().getUsername() + "; details: "
-                    + authEvent.getAuthentication().getDetails());
-            }
-        }
-
-        if (event instanceof AuthenticationFailureDisabledEvent) {
-            AuthenticationFailureDisabledEvent authEvent = (AuthenticationFailureDisabledEvent) event;
-
-            if (logger.isWarnEnabled()) {
-                logger.warn(
-                    "Authentication failed due to account being disabled for user: "
-                    + authEvent.getUser().getUsername() + "; details: "
-                    + authEvent.getAuthentication().getDetails());
-            }
-        }
-
-        if (event instanceof AuthenticationFailureAccountLockedEvent) {
-            AuthenticationFailureAccountLockedEvent authEvent = (AuthenticationFailureAccountLockedEvent) event;
-
-            if (logger.isWarnEnabled()) {
-                logger.warn(
-                    "Authentication failed due to account being locked for user: "
-                    + authEvent.getUser().getUsername() + "; details: "
-                    + authEvent.getAuthentication().getDetails());
-            }
-        }
-
-        if (event instanceof AuthenticationFailureCredentialsExpiredEvent) {
-            AuthenticationFailureCredentialsExpiredEvent authEvent = (AuthenticationFailureCredentialsExpiredEvent) event;
-
-            if (logger.isWarnEnabled()) {
-                logger.warn(
-                    "Authentication failed due to account credentials have been expired for user: "
-                    + authEvent.getUser().getUsername() + "; details: "
-                    + authEvent.getAuthentication().getDetails());
-            }
-        }
-
-        if (event instanceof AuthenticationFailureAccountExpiredEvent) {
-            AuthenticationFailureAccountExpiredEvent authEvent = (AuthenticationFailureAccountExpiredEvent) event;
-
-            if (logger.isWarnEnabled()) {
-                logger.warn(
-                    "Authentication failed due to account having expired for user: "
-                    + authEvent.getUser().getUsername() + "; details: "
-                    + authEvent.getAuthentication().getDetails());
-            }
-        }
-
-        if (event instanceof AuthenticationFailureUsernameNotFoundEvent) {
-            AuthenticationFailureUsernameNotFoundEvent authEvent = (AuthenticationFailureUsernameNotFoundEvent) event;
-
-            if (logger.isWarnEnabled()) {
-                logger.warn(
-                    "Authentication failed due to nonexistent username: "
-                    + authEvent.getUser().getUsername() + "; details: "
-                    + authEvent.getAuthentication().getDetails());
-            }
-        }
-
-        if (event instanceof AuthenticationFailureUsernameOrPasswordEvent) {
-            AuthenticationFailureUsernameOrPasswordEvent authEvent = (AuthenticationFailureUsernameOrPasswordEvent) event;
-
-            if (logger.isWarnEnabled()) {
-                logger.warn(
-                    "Authentication failed due to invalid username or password: "
-                    + authEvent.getUser().getUsername() + "; details: "
-                    + authEvent.getAuthentication().getDetails());
-            }
-        }
-
-        if (event instanceof AuthenticationSuccessEvent) {
-            AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event;
-
-            if (logger.isInfoEnabled()) {
-                logger.info("Authentication success for user: "
-                    + authEvent.getUser().getUsername() + "; details: "
-                    + authEvent.getAuthentication().getDetails());
-            }
-        }
-    }
-}

+ 1 - 2
core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java

@@ -24,11 +24,10 @@ import net.sf.acegisecurity.DisabledException;
 import net.sf.acegisecurity.GrantedAuthority;
 import net.sf.acegisecurity.UserDetails;
 import net.sf.acegisecurity.context.SecurityContextHolder;
+import net.sf.acegisecurity.event.authentication.AuthenticationSwitchUserEvent;
 import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 import net.sf.acegisecurity.providers.dao.AuthenticationDao;
-import net.sf.acegisecurity.providers.dao.User;
 import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
-import net.sf.acegisecurity.providers.dao.event.AuthenticationSwitchUserEvent;
 import net.sf.acegisecurity.ui.WebAuthenticationDetails;
 
 import org.apache.commons.logging.Log;

+ 16 - 45
core/src/test/java/org/acegisecurity/providers/dao/event/AuthenticationEventTests.java → core/src/test/java/org/acegisecurity/event/authentication/AuthenticationEventTests.java

@@ -13,19 +13,18 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.providers.dao.event;
+package net.sf.acegisecurity.event.authentication;
 
 import junit.framework.TestCase;
 
 import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.GrantedAuthority;
-import net.sf.acegisecurity.GrantedAuthorityImpl;
+import net.sf.acegisecurity.AuthenticationException;
+import net.sf.acegisecurity.DisabledException;
 import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
-import net.sf.acegisecurity.providers.dao.User;
 
 
 /**
- * Tests {@link AuthenticationEvent} and its subclasses.
+ * Tests {@link AbstractAuthenticationEvent} and its subclasses.
  *
  * @author Ben Alex
  * @version $Id$
@@ -41,63 +40,42 @@ public class AuthenticationEventTests extends TestCase {
         junit.textui.TestRunner.run(AuthenticationEventTests.class);
     }
 
-    public void testDisabledEvent() {
+    public void testAbstractAuthenticationEvent() {
         Authentication auth = getAuthentication();
-        User user = getUser();
-        AuthenticationFailureDisabledEvent event = new AuthenticationFailureDisabledEvent(auth,
-                user);
+        AbstractAuthenticationEvent event = new AuthenticationSuccessEvent(auth);
         assertEquals(auth, event.getAuthentication());
-        assertEquals(user, event.getUser());
     }
 
-    public void testPasswordEvent() {
+    public void testAbstractAuthenticationFailureEvent() {
         Authentication auth = getAuthentication();
-        User user = getUser();
-        AuthenticationFailurePasswordEvent event = new AuthenticationFailurePasswordEvent(auth,
-                user);
+        AuthenticationException exception = new DisabledException("TEST");
+        AbstractAuthenticationFailureEvent event = new AuthenticationFailureDisabledEvent(auth,
+                exception);
         assertEquals(auth, event.getAuthentication());
-        assertEquals(user, event.getUser());
+        assertEquals(exception, event.getException());
     }
 
     public void testRejectsNullAuthentication() {
+        AuthenticationException exception = new DisabledException("TEST");
+
         try {
             AuthenticationFailureDisabledEvent event = new AuthenticationFailureDisabledEvent(null,
-                    getUser());
+                    exception);
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
     }
 
-    public void testRejectsNullUser() {
+    public void testRejectsNullAuthenticationException() {
         try {
-            AuthenticationFailureDisabledEvent event = new AuthenticationFailureDisabledEvent(getAuthentication(),
-                    null);
+            new AuthenticationFailureDisabledEvent(getAuthentication(), null);
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
     }
 
-    public void testSuccessEvent() {
-        Authentication auth = getAuthentication();
-        User user = getUser();
-        AuthenticationSuccessEvent event = new AuthenticationSuccessEvent(auth,
-                user);
-        assertEquals(auth, event.getAuthentication());
-        assertEquals(user, event.getUser());
-    }
-
-    public void testSwitchUserContextEvent() {
-        Authentication auth = getAuthentication();
-        User targetUser = getUser();
-
-        AuthenticationSwitchUserEvent event = new AuthenticationSwitchUserEvent(auth,
-                targetUser);
-        assertEquals(auth, event.getAuthentication());
-        assertEquals(targetUser, event.getUser());
-    }
-
     private Authentication getAuthentication() {
         UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal",
                 "Credentials");
@@ -105,11 +83,4 @@ public class AuthenticationEventTests extends TestCase {
 
         return authentication;
     }
-
-    private User getUser() {
-        User user = new User("foo", "bar", true, true, true, true,
-                new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOOBAR")});
-
-        return user;
-    }
 }

+ 57 - 0
core/src/test/java/org/acegisecurity/event/authentication/LoggerListenerTests.java

@@ -0,0 +1,57 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.event.authentication;
+
+import junit.framework.TestCase;
+
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.LockedException;
+import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+
+
+/**
+ * Tests {@link LoggerListener}.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class LoggerListenerTests extends TestCase {
+    //~ Methods ================================================================
+
+    public final void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(LoggerListenerTests.class);
+    }
+
+    public void testLogsEvents() {
+        AuthenticationFailureDisabledEvent event = new AuthenticationFailureDisabledEvent(getAuthentication(),
+                new LockedException("TEST"));
+        LoggerListener listener = new LoggerListener();
+        listener.onApplicationEvent(event);
+        assertTrue(true);
+    }
+
+    private Authentication getAuthentication() {
+        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal",
+                "Credentials");
+        authentication.setDetails("127.0.0.1");
+
+        return authentication;
+    }
+}

+ 9 - 9
core/src/test/java/org/acegisecurity/intercept/event/AuthenticationCredentialsNotFoundEventTests.java → core/src/test/java/org/acegisecurity/event/authorization/AuthenticationCredentialsNotFoundEventTests.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 import junit.framework.TestCase;
 
@@ -47,25 +47,25 @@ public class AuthenticationCredentialsNotFoundEventTests extends TestCase {
 
     public void testRejectsNulls() {
         try {
-            AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(null,
-                    new ConfigAttributeDefinition(),
-                    new AuthenticationCredentialsNotFoundException("test"));
+            new AuthenticationCredentialsNotFoundEvent(null,
+                new ConfigAttributeDefinition(),
+                new AuthenticationCredentialsNotFoundException("test"));
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
 
         try {
-            AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(new MockMethodInvocation(),
-                    null, new AuthenticationCredentialsNotFoundException("test"));
+            new AuthenticationCredentialsNotFoundEvent(new MockMethodInvocation(),
+                null, new AuthenticationCredentialsNotFoundException("test"));
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
 
         try {
-            AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(new MockMethodInvocation(),
-                    new ConfigAttributeDefinition(), null);
+            new AuthenticationCredentialsNotFoundEvent(new MockMethodInvocation(),
+                new ConfigAttributeDefinition(), null);
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);

+ 16 - 16
core/src/test/java/org/acegisecurity/intercept/event/AuthorizationFailureEventTests.java → core/src/test/java/org/acegisecurity/event/authorization/AuthorizationFailureEventTests.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,13 +13,14 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 import junit.framework.TestCase;
 
 import net.sf.acegisecurity.AccessDeniedException;
 import net.sf.acegisecurity.ConfigAttributeDefinition;
 import net.sf.acegisecurity.MockMethodInvocation;
+import net.sf.acegisecurity.event.authorization.AuthorizationFailureEvent;
 import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 
 
@@ -48,38 +49,37 @@ public class AuthorizationFailureEventTests extends TestCase {
 
     public void testRejectsNulls() {
         try {
-            AuthorizationFailureEvent event = new AuthorizationFailureEvent(null,
-                    new ConfigAttributeDefinition(),
-                    new UsernamePasswordAuthenticationToken("foo", "bar"),
-                    new AccessDeniedException("error"));
+            new AuthorizationFailureEvent(null,
+                new ConfigAttributeDefinition(),
+                new UsernamePasswordAuthenticationToken("foo", "bar"),
+                new AccessDeniedException("error"));
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
 
         try {
-            AuthorizationFailureEvent event = new AuthorizationFailureEvent(new MockMethodInvocation(),
-                    null,
-                    new UsernamePasswordAuthenticationToken("foo", "bar"),
-                    new AccessDeniedException("error"));
+            new AuthorizationFailureEvent(new MockMethodInvocation(), null,
+                new UsernamePasswordAuthenticationToken("foo", "bar"),
+                new AccessDeniedException("error"));
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
 
         try {
-            AuthorizationFailureEvent event = new AuthorizationFailureEvent(new MockMethodInvocation(),
-                    new ConfigAttributeDefinition(), null,
-                    new AccessDeniedException("error"));
+            new AuthorizationFailureEvent(new MockMethodInvocation(),
+                new ConfigAttributeDefinition(), null,
+                new AccessDeniedException("error"));
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
 
         try {
-            AuthorizationFailureEvent event = new AuthorizationFailureEvent(new MockMethodInvocation(),
-                    new ConfigAttributeDefinition(),
-                    new UsernamePasswordAuthenticationToken("foo", "bar"), null);
+            new AuthorizationFailureEvent(new MockMethodInvocation(),
+                new ConfigAttributeDefinition(),
+                new UsernamePasswordAuthenticationToken("foo", "bar"), null);
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);

+ 8 - 9
core/src/test/java/org/acegisecurity/intercept/event/AuthorizedEventTests.java → core/src/test/java/org/acegisecurity/event/authorization/AuthorizedEventTests.java

@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package net.sf.acegisecurity.intercept.event;
+package net.sf.acegisecurity.event.authorization;
 
 import junit.framework.TestCase;
 
@@ -47,25 +47,24 @@ public class AuthorizedEventTests extends TestCase {
 
     public void testRejectsNulls() {
         try {
-            AuthorizedEvent event = new AuthorizedEvent(null,
-                    new ConfigAttributeDefinition(),
-                    new UsernamePasswordAuthenticationToken("foo", "bar"));
+            new AuthorizedEvent(null, new ConfigAttributeDefinition(),
+                new UsernamePasswordAuthenticationToken("foo", "bar"));
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
 
         try {
-            AuthorizedEvent event = new AuthorizedEvent(new MockMethodInvocation(),
-                    null, new UsernamePasswordAuthenticationToken("foo", "bar"));
+            new AuthorizedEvent(new MockMethodInvocation(), null,
+                new UsernamePasswordAuthenticationToken("foo", "bar"));
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);
         }
 
         try {
-            AuthorizedEvent event = new AuthorizedEvent(new MockMethodInvocation(),
-                    new ConfigAttributeDefinition(), null);
+            new AuthorizedEvent(new MockMethodInvocation(),
+                new ConfigAttributeDefinition(), null);
             fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException expected) {
             assertTrue(true);

+ 0 - 88
core/src/test/java/org/acegisecurity/intercept/event/AuthenticationFailureEventTests.java

@@ -1,88 +0,0 @@
-/* Copyright 2004 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.sf.acegisecurity.intercept.event;
-
-import junit.framework.TestCase;
-
-import net.sf.acegisecurity.BadCredentialsException;
-import net.sf.acegisecurity.ConfigAttributeDefinition;
-import net.sf.acegisecurity.MockMethodInvocation;
-import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
-
-
-/**
- * Tests {@link AuthenticationFailureEvent}.
- *
- * @author Ben Alex
- * @version $Id$
- */
-public class AuthenticationFailureEventTests extends TestCase {
-    //~ Constructors ===========================================================
-
-    public AuthenticationFailureEventTests() {
-        super();
-    }
-
-    public AuthenticationFailureEventTests(String arg0) {
-        super(arg0);
-    }
-
-    //~ Methods ================================================================
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AuthenticationFailureEventTests.class);
-    }
-
-    public void testRejectsNulls() {
-        try {
-            AuthenticationFailureEvent event = new AuthenticationFailureEvent(null,
-                    new ConfigAttributeDefinition(),
-                    new UsernamePasswordAuthenticationToken("foo", "bar"),
-                    new BadCredentialsException("error"));
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertTrue(true);
-        }
-
-        try {
-            AuthenticationFailureEvent event = new AuthenticationFailureEvent(new MockMethodInvocation(),
-                    null,
-                    new UsernamePasswordAuthenticationToken("foo", "bar"),
-                    new BadCredentialsException("error"));
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertTrue(true);
-        }
-
-        try {
-            AuthenticationFailureEvent event = new AuthenticationFailureEvent(new MockMethodInvocation(),
-                    new ConfigAttributeDefinition(), null,
-                    new BadCredentialsException("error"));
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertTrue(true);
-        }
-
-        try {
-            AuthenticationFailureEvent event = new AuthenticationFailureEvent(new MockMethodInvocation(),
-                    new ConfigAttributeDefinition(),
-                    new UsernamePasswordAuthenticationToken("foo", "bar"), null);
-            fail("Should have thrown IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-            assertTrue(true);
-        }
-    }
-}

+ 31 - 6
core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java

@@ -15,14 +15,20 @@
 
 package net.sf.acegisecurity.providers;
 
-import junit.framework.TestCase;
+import java.util.List;
+import java.util.Vector;
 
-import net.sf.acegisecurity.*;
+import junit.framework.TestCase;
+import net.sf.acegisecurity.Authentication;
+import net.sf.acegisecurity.AuthenticationException;
+import net.sf.acegisecurity.AuthenticationServiceException;
+import net.sf.acegisecurity.GrantedAuthority;
+import net.sf.acegisecurity.GrantedAuthorityImpl;
 import net.sf.acegisecurity.concurrent.ConcurrentSessionControllerImpl;
 import net.sf.acegisecurity.concurrent.NullConcurrentSessionController;
 
-import java.util.List;
-import java.util.Vector;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
 
 
 /**
@@ -59,6 +65,7 @@ public class ProviderManagerTests extends TestCase {
                         "ROLE_TWO")});
 
         ProviderManager mgr = makeProviderManager();
+        mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
 
         try {
             mgr.authenticate(token);
@@ -68,13 +75,14 @@ public class ProviderManagerTests extends TestCase {
         }
     }
 
-    public void testAuthenticationSuccess() {
+    public void testAuthenticationSuccess() throws Exception {
         TestingAuthenticationToken token = new TestingAuthenticationToken("Test",
                 "Password",
                 new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
                         "ROLE_TWO")});
 
         ProviderManager mgr = makeProviderManager();
+        mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
         Authentication result = mgr.authenticate(token);
 
         if (!(result instanceof TestingAuthenticationToken)) {
@@ -95,6 +103,7 @@ public class ProviderManagerTests extends TestCase {
                         "ROLE_TWO")});
 
         ProviderManager mgr = makeProviderManagerWithMockProviderWhichReturnsNullInList();
+        mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
         Authentication result = mgr.authenticate(token);
 
         if (!(result instanceof TestingAuthenticationToken)) {
@@ -166,14 +175,16 @@ public class ProviderManagerTests extends TestCase {
         assertEquals(1, mgr.getProviders().size());
     }
 
-    private ProviderManager makeProviderManager() {
+    private ProviderManager makeProviderManager() throws Exception {
         MockProvider provider1 = new MockProvider();
         List providers = new Vector();
         providers.add(provider1);
 
         ProviderManager mgr = new ProviderManager();
         mgr.setProviders(providers);
+        
 
+        mgr.afterPropertiesSet();
         return mgr;
     }
 
@@ -233,4 +244,18 @@ public class ProviderManagerTests extends TestCase {
             }
         }
     }
+    
+    private class MockApplicationEventPublisher implements ApplicationEventPublisher {
+		private boolean expectedEvent;
+    	
+		public MockApplicationEventPublisher(boolean expectedEvent) {
+			this.expectedEvent = expectedEvent;
+		}
+		
+    	public void publishEvent(ApplicationEvent event) {
+			if (expectedEvent == false) {
+				throw new IllegalStateException("The ApplicationEventPublisher did not expect to receive this event");				
+			}
+		}
+    }
 }

+ 2 - 50
core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java

@@ -34,8 +34,6 @@ import net.sf.acegisecurity.providers.dao.cache.NullUserCache;
 import net.sf.acegisecurity.providers.dao.salt.SystemWideSaltSource;
 import net.sf.acegisecurity.providers.encoding.ShaPasswordEncoder;
 
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
 import org.springframework.dao.DataAccessException;
 import org.springframework.dao.DataRetrievalFailureException;
 
@@ -67,8 +65,6 @@ public class DaoAuthenticationProviderTests extends TestCase {
         DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
         provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
         provider.setUserCache(new MockUserCache());
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
 
         try {
             provider.authenticate(token);
@@ -92,16 +88,6 @@ public class DaoAuthenticationProviderTests extends TestCase {
         } catch (AccountExpiredException expected) {
             assertTrue(true);
         }
-
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
-
-        try {
-            provider.authenticate(token);
-            fail("Should have thrown AccountExpiredException");
-        } catch (AccountExpiredException expected) {
-            assertTrue(true);
-        }
     }
 
     public void testAuthenticateFailsIfAccountLocked() {
@@ -118,16 +104,6 @@ public class DaoAuthenticationProviderTests extends TestCase {
         } catch (LockedException expected) {
             assertTrue(true);
         }
-
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
-
-        try {
-            provider.authenticate(token);
-            fail("Should have thrown CredentialsExpiredException");
-        } catch (LockedException expected) {
-            assertTrue(true);
-        }
     }
 
     public void testAuthenticateFailsIfCredentialsExpired() {
@@ -145,18 +121,9 @@ public class DaoAuthenticationProviderTests extends TestCase {
             assertTrue(true);
         }
 
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
-
-        try {
-            provider.authenticate(token);
-            fail("Should have thrown CredentialsExpiredException");
-        } catch (CredentialsExpiredException expected) {
-            assertTrue(true);
-        }
-
         // Check that wrong password causes BadCredentialsException, rather than CredentialsExpiredException
-        token = new UsernamePasswordAuthenticationToken("peter", "wrong_password");
+        token = new UsernamePasswordAuthenticationToken("peter",
+                "wrong_password");
 
         try {
             provider.authenticate(token);
@@ -180,16 +147,6 @@ public class DaoAuthenticationProviderTests extends TestCase {
         } catch (DisabledException expected) {
             assertTrue(true);
         }
-
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
-
-        try {
-            provider.authenticate(token);
-            fail("Should have thrown DisabledException");
-        } catch (DisabledException expected) {
-            assertTrue(true);
-        }
     }
 
     public void testAuthenticateFailsWhenAuthenticationDaoHasBackendFailure() {
@@ -422,11 +379,6 @@ public class DaoAuthenticationProviderTests extends TestCase {
         assertFalse(provider.isForcePrincipalAsString());
         provider.setForcePrincipalAsString(true);
         assertTrue(provider.isForcePrincipalAsString());
-
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
-        assertEquals(ClassPathXmlApplicationContext.class.getName(),
-            provider.getContext().getClass().getName());
     }
 
     public void testGoesBackToAuthenticationDaoToObtainLatestPasswordIfCachedPasswordSeemsIncorrect() {

+ 0 - 32
core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java

@@ -32,8 +32,6 @@ import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 import net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache;
 import net.sf.acegisecurity.providers.dao.cache.NullUserCache;
 
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
 import org.springframework.dao.DataAccessException;
 import org.springframework.dao.DataRetrievalFailureException;
 
@@ -87,16 +85,6 @@ public class PasswordDaoAuthenticationProviderTests extends TestCase {
         } catch (AccountExpiredException expected) {
             assertTrue(true);
         }
-
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
-
-        try {
-            provider.authenticate(token);
-            fail("Should have thrown AccountExpiredException");
-        } catch (AccountExpiredException expected) {
-            assertTrue(true);
-        }
     }
 
     public void testAuthenticateFailsIfAccountLocked() {
@@ -113,16 +101,6 @@ public class PasswordDaoAuthenticationProviderTests extends TestCase {
         } catch (LockedException expected) {
             assertTrue(true);
         }
-
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
-
-        try {
-            provider.authenticate(token);
-            fail("Should have thrown AccountExpiredException");
-        } catch (LockedException expected) {
-            assertTrue(true);
-        }
     }
 
     public void testAuthenticateFailsIfCredentialsExpired() {
@@ -139,16 +117,6 @@ public class PasswordDaoAuthenticationProviderTests extends TestCase {
         } catch (CredentialsExpiredException expected) {
             assertTrue(true);
         }
-
-        provider.setApplicationContext(new ClassPathXmlApplicationContext(
-                "net/sf/acegisecurity/util/filtertest-valid.xml"));
-
-        try {
-            provider.authenticate(token);
-            fail("Should have thrown CredentialsExpiredException");
-        } catch (CredentialsExpiredException expected) {
-            assertTrue(true);
-        }
     }
 
     public void testAuthenticateFailsIfUserDisabled() {

+ 0 - 98
core/src/test/java/org/acegisecurity/providers/dao/event/LoggerListenerTests.java

@@ -1,98 +0,0 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.sf.acegisecurity.providers.dao.event;
-
-import junit.framework.TestCase;
-
-import net.sf.acegisecurity.Authentication;
-import net.sf.acegisecurity.GrantedAuthority;
-import net.sf.acegisecurity.GrantedAuthorityImpl;
-import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
-import net.sf.acegisecurity.providers.dao.User;
-
-
-/**
- * Tests {@link LoggerListener}.
- *
- * @author Ben Alex
- * @version $Id$
- */
-public class LoggerListenerTests extends TestCase {
-    //~ Methods ================================================================
-
-    public final void setUp() throws Exception {
-        super.setUp();
-    }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(LoggerListenerTests.class);
-    }
-
-    public void testLogsDisabledEvents() {
-        AuthenticationFailureDisabledEvent event = new AuthenticationFailureDisabledEvent(getAuthentication(),
-                getUser());
-        LoggerListener listener = new LoggerListener();
-        listener.onApplicationEvent(event);
-        assertTrue(true);
-    }
-
-    public void testLogsPasswordEvents() {
-        AuthenticationFailurePasswordEvent event = new AuthenticationFailurePasswordEvent(getAuthentication(),
-                getUser());
-        LoggerListener listener = new LoggerListener();
-        listener.onApplicationEvent(event);
-        assertTrue(true);
-    }
-
-    public void testLogsSuccessEvents() {
-        AuthenticationSuccessEvent event = new AuthenticationSuccessEvent(getAuthentication(),
-                getUser());
-        LoggerListener listener = new LoggerListener();
-        listener.onApplicationEvent(event);
-        assertTrue(true);
-    }
-
-    public void testLogsUsernameNotFoundEvents() {
-        AuthenticationFailureUsernameNotFoundEvent event = new AuthenticationFailureUsernameNotFoundEvent(getAuthentication(),
-                getUser());
-        LoggerListener listener = new LoggerListener();
-        listener.onApplicationEvent(event);
-        assertTrue(true);
-    }
-
-    public void testLogsUsernameOfPasswordEvent() {
-        AuthenticationFailureUsernameOrPasswordEvent event = new AuthenticationFailureUsernameOrPasswordEvent(getAuthentication(),
-                getUser());
-        LoggerListener listener = new LoggerListener();
-        listener.onApplicationEvent(event);
-        assertTrue(true);
-    }
-
-    private Authentication getAuthentication() {
-        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal",
-                "Credentials");
-        authentication.setDetails("127.0.0.1");
-
-        return authentication;
-    }
-
-    private User getUser() {
-        User user = new User("foo", "bar", true, true, true, true,
-                new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOOBAR")});
-
-        return user;
-    }
-}

+ 2 - 2
core/src/test/resources/org/acegisecurity/applicationContext.xml

@@ -21,10 +21,10 @@
 <beans>
 
    <!-- Automatically receives AuthenticationEvent messages from DaoAuthenticationProvider -->
-   <bean id="authenticationLoggerListener" class="net.sf.acegisecurity.providers.dao.event.LoggerListener"/>
+   <bean id="authenticationLoggerListener" class="net.sf.acegisecurity.event.authentication.LoggerListener"/>
 
    <!-- Automatically receives AuthenticationEvent messages from AbstractSecurityInterceptor -->
-   <bean id="secureObjectLoggerListener" class="net.sf.acegisecurity.intercept.event.LoggerListener"/>
+   <bean id="secureObjectLoggerListener" class="net.sf.acegisecurity.event.authorization.LoggerListener"/>
 
    <!-- Setup a cache we can use in tests of the caching layer -->
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">

+ 1 - 1
core/src/test/resources/org/acegisecurity/intercept/method/aopalliance/applicationContext.xml

@@ -25,7 +25,7 @@
 	<bean id="accessDecision" class="net.sf.acegisecurity.MockAccessDecisionManager"/>
 	<bean id="runAs" class="net.sf.acegisecurity.MockRunAsManager"/>
 
-	<bean id="loggerListener" class="net.sf.acegisecurity.intercept.event.LoggerListener"/>
+   <bean id="secureObjectLoggerListener" class="net.sf.acegisecurity.event.authorization.LoggerListener"/>
 
 	<bean id="securityInterceptor" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
 		<property name="authenticationManager"><ref local="authentication"/></property>

+ 1 - 1
core/src/test/resources/org/acegisecurity/intercept/method/applicationContext.xml

@@ -50,6 +50,6 @@
       </property>
     </bean>
 
-	<bean id="loggerListener" class="net.sf.acegisecurity.intercept.event.LoggerListener"/>
+   <bean id="secureObjectLoggerListener" class="net.sf.acegisecurity.event.authorization.LoggerListener"/>
 
 </beans>

+ 3 - 0
doc/xdocs/upgrade/upgrade-080-090.html

@@ -46,6 +46,9 @@ applications:
     set this property to false if you would like the anoymous authentication token to be preserved,
     which would be an unusual requirement.<br><br></li>
     
+	<li>Event publishing has been refactored. New event classes have been added, and the location of
+	LoggerListener has changed. See the net.sf.acegisecurity.event package.</li>
+		
     </ul>
 
 </body>

+ 2 - 2
samples/contacts-tiger/src/main/webapp/filter/WEB-INF/applicationContext-acegi-security.xml

@@ -65,8 +65,8 @@
       <property name="cache"><ref local="userCacheBackend"/></property>
    </bean>
 
-   <!-- Automatically receives AuthenticationEvent messages from DaoAuthenticationProvider -->
-   <bean id="loggerListener" class="net.sf.acegisecurity.providers.dao.event.LoggerListener"/>
+   <!-- Automatically receives AuthenticationEvent messages -->
+   <bean id="loggerListener" class="net.sf.acegisecurity.event.authentication.LoggerListener"/>
 
    <bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter">
       <property name="authenticationManager"><ref local="authenticationManager"/></property>

+ 2 - 2
samples/contacts/src/main/webapp/filter/WEB-INF/applicationContext-acegi-security.xml

@@ -65,8 +65,8 @@
       <property name="cache"><ref local="userCacheBackend"/></property>
    </bean>
 
-   <!-- Automatically receives AuthenticationEvent messages from DaoAuthenticationProvider -->
-   <bean id="loggerListener" class="net.sf.acegisecurity.providers.dao.event.LoggerListener"/>
+   <!-- Automatically receives AuthenticationEvent messages -->
+   <bean id="loggerListener" class="net.sf.acegisecurity.event.authentication.LoggerListener"/>
 
    <bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter">
       <property name="authenticationManager"><ref local="authenticationManager"/></property>