Add InteractiveAuthenticationSuccessEvent handling to authentication mechanisms.

This commit is contained in:
Ben Alex 2005-06-27 03:34:36 +00:00
parent 60f8095cf2
commit 5c883e639f
4 changed files with 161 additions and 19 deletions

View File

@ -27,6 +27,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import java.io.IOException;
@ -113,13 +116,21 @@ import javax.servlet.http.HttpServletResponse;
* <code>authenticationFailureUrl</code>
* </p>
*
* <p>
* If authentication is successful, an {@link
* net.sf.acegisecurity.ui.InteractiveAuthenticationSuccesEvent} will be
* published to the application context. No events will be published if
* authentication was unsuccessful, because this would generally be recorded
* via an <code>AuthenticationManager</code>-specific application event.
* </p>
*
* @author Ben Alex
* @author colin sampaleanu
* @author Ray Krueger
* @version $Id$
*/
public abstract class AbstractProcessingFilter implements Filter,
InitializingBean {
InitializingBean, ApplicationContextAware {
//~ Static fields/initializers =============================================
public static final String ACEGI_SECURITY_TARGET_URL_KEY = "ACEGI_SECURITY_TARGET_URL";
@ -128,6 +139,7 @@ public abstract class AbstractProcessingFilter implements Filter,
//~ Instance fields ========================================================
private ApplicationContext context;
private AuthenticationManager authenticationManager;
private Properties exceptionMappings = new Properties();
private RememberMeServices rememberMeServices = new NullRememberMeServices();
@ -172,6 +184,10 @@ public abstract class AbstractProcessingFilter implements Filter,
return alwaysUseDefaultTargetUrl;
}
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
public void setContinueChainBeforeSuccessfulAuthentication(
boolean continueChainBeforeSuccessfulAuthentication) {
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
@ -189,6 +205,14 @@ public abstract class AbstractProcessingFilter implements Filter,
*/
public abstract String getDefaultFilterProcessesUrl();
public void setDefaultTargetUrl(String defaultTargetUrl) {
this.defaultTargetUrl = defaultTargetUrl;
}
public String getDefaultTargetUrl() {
return defaultTargetUrl;
}
public void setExceptionMappings(Properties exceptionMappings) {
this.exceptionMappings = exceptionMappings;
}
@ -197,6 +221,14 @@ public abstract class AbstractProcessingFilter implements Filter,
return new Properties(exceptionMappings);
}
public void setFilterProcessesUrl(String filterProcessesUrl) {
this.filterProcessesUrl = filterProcessesUrl;
}
public String getFilterProcessesUrl() {
return filterProcessesUrl;
}
public void setRememberMeServices(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices;
}
@ -235,22 +267,6 @@ public abstract class AbstractProcessingFilter implements Filter,
return authenticationManager;
}
public void setDefaultTargetUrl(String defaultTargetUrl) {
this.defaultTargetUrl = defaultTargetUrl;
}
public String getDefaultTargetUrl() {
return defaultTargetUrl;
}
public void setFilterProcessesUrl(String filterProcessesUrl) {
this.filterProcessesUrl = filterProcessesUrl;
}
public String getFilterProcessesUrl() {
return filterProcessesUrl;
}
public void afterPropertiesSet() throws Exception {
Assert.hasLength(filterProcessesUrl,
"filterProcessesUrl must be specified");
@ -403,6 +419,12 @@ public abstract class AbstractProcessingFilter implements Filter,
rememberMeServices.loginSuccess(request, response, authResult);
// Fire event
if (this.context != null) {
context.publishEvent(new InteractiveAuthenticationSuccesEvent(
authResult, this.getClass()));
}
response.sendRedirect(response.encodeRedirectURL(targetUrl));
}

View File

@ -0,0 +1,71 @@
/* 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.ui;
import net.sf.acegisecurity.Authentication;
import org.springframework.context.ApplicationEvent;
import org.springframework.util.Assert;
/**
* Indicates an interactive authentication was successful.
*
* <P>
* The <code>ApplicationEvent</code>'s <code>source</code> will be the
* <code>Authentication</code> object.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class InteractiveAuthenticationSuccesEvent extends ApplicationEvent {
//~ Instance fields ========================================================
private Class generatedBy;
//~ Constructors ===========================================================
public InteractiveAuthenticationSuccesEvent(Authentication authentication,
Class generatedBy) {
super(authentication);
Assert.notNull(generatedBy);
this.generatedBy = generatedBy;
}
//~ Methods ================================================================
/**
* Getters for the <code>Authentication</code> request that caused the
* event. Also available from <code>super.getSource()</code>.
*
* @return the authentication request
*/
public Authentication getAuthentication() {
return (Authentication) super.getSource();
}
/**
* Getter for the <code>Class</code> that generated this event. This can be
* useful for generating additional logging information.
*
* @return
*/
public Class getGeneratedBy() {
return generatedBy;
}
}

View File

@ -16,12 +16,16 @@
package net.sf.acegisecurity.ui.rememberme;
import net.sf.acegisecurity.context.SecurityContextHolder;
import net.sf.acegisecurity.ui.InteractiveAuthenticationSuccesEvent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import java.io.IOException;
@ -52,6 +56,14 @@ import javax.servlet.http.HttpServletResponse;
* will be placed into the <code>SecurityContext</code>.
* </p>
*
* <p>
* If authentication is successful, an {@link
* net.sf.acegisecurity.ui.InteractiveAuthenticationSuccesEvent} will be
* published to the application context. No events will be published if
* authentication was unsuccessful, because this would generally be recorded
* via an <code>AuthenticationManager</code>-specific application event.
* </p>
*
* <P>
* <B>Do not use this class directly.</B> Instead configure
* <code>web.xml</code> to use the {@link
@ -61,17 +73,23 @@ import javax.servlet.http.HttpServletResponse;
* @author Ben Alex
* @version $Id$
*/
public class RememberMeProcessingFilter implements Filter, InitializingBean {
public class RememberMeProcessingFilter implements Filter, InitializingBean,
ApplicationContextAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(RememberMeProcessingFilter.class);
//~ Instance fields ========================================================
private ApplicationContext context;
private RememberMeServices rememberMeServices = new NullRememberMeServices();
//~ Methods ================================================================
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
public void setRememberMeServices(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices;
}
@ -112,6 +130,13 @@ public class RememberMeProcessingFilter implements Filter, InitializingBean {
+ SecurityContextHolder.getContext().getAuthentication()
+ "'");
}
// Fire event
if (this.context != null) {
context.publishEvent(new InteractiveAuthenticationSuccesEvent(
SecurityContextHolder.getContext().getAuthentication(),
this.getClass()));
}
} else {
if (logger.isDebugEnabled()) {
logger.debug(

View File

@ -21,6 +21,7 @@ import net.sf.acegisecurity.AuthenticationManager;
import net.sf.acegisecurity.context.SecurityContextHolder;
import net.sf.acegisecurity.providers.x509.X509AuthenticationToken;
import net.sf.acegisecurity.ui.AbstractProcessingFilter;
import net.sf.acegisecurity.ui.InteractiveAuthenticationSuccesEvent;
import net.sf.acegisecurity.ui.WebAuthenticationDetails;
import org.apache.commons.logging.Log;
@ -28,6 +29,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import java.io.IOException;
@ -55,6 +59,14 @@ import javax.servlet.http.HttpServletResponse;
* </p>
*
* <p>
* If authentication is successful, an {@link
* net.sf.acegisecurity.ui.InteractiveAuthenticationSuccesEvent} will be
* published to the application context. No events will be published if
* authentication was unsuccessful, because this would generally be recorded
* via an <code>AuthenticationManager</code>-specific application event.
* </p>
*
* <p>
* <b>Do not use this class directly.</b> Instead configure
* <code>web.xml</code> to use the {@link
* net.sf.acegisecurity.util.FilterToBeanProxy}.
@ -63,17 +75,23 @@ import javax.servlet.http.HttpServletResponse;
* @author Luke Taylor
* @version $Id$
*/
public class X509ProcessingFilter implements Filter, InitializingBean {
public class X509ProcessingFilter implements Filter, InitializingBean,
ApplicationContextAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(X509ProcessingFilter.class);
//~ Instance fields ========================================================
private ApplicationContext context;
private AuthenticationManager authenticationManager;
//~ Methods ================================================================
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
@ -167,6 +185,12 @@ public class X509ProcessingFilter implements Filter, InitializingBean {
}
SecurityContextHolder.getContext().setAuthentication(authResult);
// Fire event
if (this.context != null) {
context.publishEvent(new InteractiveAuthenticationSuccesEvent(
authResult, this.getClass()));
}
}
/**