SEC-70: Refactor event publishing.

This commit is contained in:
Ben Alex 2005-11-03 06:55:47 +00:00
parent 3811200599
commit b6dbfde55c
48 changed files with 637 additions and 998 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}
}

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 ===========================================================
/**

View File

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

View File

@ -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>

View File

@ -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;
}
}

View File

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

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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.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;

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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");
}
}
}
}

View File

@ -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() {

View File

@ -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() {

View File

@ -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;
}
}

View File

@ -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">

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>