|
@@ -16,8 +16,10 @@
|
|
|
package net.sf.acegisecurity.intercept;
|
|
|
|
|
|
import net.sf.acegisecurity.AccessDecisionManager;
|
|
|
+import net.sf.acegisecurity.AccessDeniedException;
|
|
|
import net.sf.acegisecurity.Authentication;
|
|
|
import net.sf.acegisecurity.AuthenticationCredentialsNotFoundException;
|
|
|
+import net.sf.acegisecurity.AuthenticationException;
|
|
|
import net.sf.acegisecurity.AuthenticationManager;
|
|
|
import net.sf.acegisecurity.ConfigAttribute;
|
|
|
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
|
@@ -25,13 +27,22 @@ import net.sf.acegisecurity.RunAsManager;
|
|
|
import net.sf.acegisecurity.context.Context;
|
|
|
import net.sf.acegisecurity.context.ContextHolder;
|
|
|
import net.sf.acegisecurity.context.SecureContext;
|
|
|
+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.runas.NullRunAsManager;
|
|
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
|
|
+import org.springframework.beans.BeansException;
|
|
|
import org.springframework.beans.factory.InitializingBean;
|
|
|
|
|
|
+import org.springframework.context.ApplicationContext;
|
|
|
+import org.springframework.context.ApplicationContextAware;
|
|
|
+
|
|
|
import java.util.HashSet;
|
|
|
import java.util.Iterator;
|
|
|
import java.util.Set;
|
|
@@ -127,7 +138,8 @@ import java.util.Set;
|
|
|
* @author Ben Alex
|
|
|
* @version $Id$
|
|
|
*/
|
|
|
-public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
+public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|
|
+ ApplicationContextAware {
|
|
|
//~ Static fields/initializers =============================================
|
|
|
|
|
|
protected static final Log logger = LogFactory.getLog(AbstractSecurityInterceptor.class);
|
|
@@ -135,12 +147,18 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
//~ Instance fields ========================================================
|
|
|
|
|
|
private AccessDecisionManager accessDecisionManager;
|
|
|
+ private ApplicationContext context;
|
|
|
private AuthenticationManager authenticationManager;
|
|
|
private RunAsManager runAsManager = new NullRunAsManager();
|
|
|
private boolean validateConfigAttributes = true;
|
|
|
|
|
|
//~ Methods ================================================================
|
|
|
|
|
|
+ public void setApplicationContext(ApplicationContext applicationContext)
|
|
|
+ throws BeansException {
|
|
|
+ this.context = applicationContext;
|
|
|
+ }
|
|
|
+
|
|
|
public abstract ObjectDefinitionSource obtainObjectDefinitionSource();
|
|
|
|
|
|
public void setAccessDecisionManager(
|
|
@@ -253,6 +271,12 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
}
|
|
|
|
|
|
protected InterceptorStatusToken beforeInvocation(Object object) {
|
|
|
+ if (this.context != null) {
|
|
|
+ System.out.println("xx");
|
|
|
+ } else {
|
|
|
+ System.out.println("null");
|
|
|
+ }
|
|
|
+
|
|
|
if (object == null) {
|
|
|
throw new IllegalArgumentException("Object was null");
|
|
|
}
|
|
@@ -275,8 +299,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
// Ensure ContextHolder presents a populated SecureContext
|
|
|
if ((ContextHolder.getContext() == null)
|
|
|
|| !(ContextHolder.getContext() instanceof SecureContext)) {
|
|
|
- throw new AuthenticationCredentialsNotFoundException(
|
|
|
- "A valid SecureContext was not provided in the RequestContext");
|
|
|
+ credentialsNotFound("A valid SecureContext was not provided in the RequestContext",
|
|
|
+ object, attr);
|
|
|
}
|
|
|
|
|
|
SecureContext context = (SecureContext) ContextHolder.getContext();
|
|
@@ -284,13 +308,27 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
// We check for just the property we're interested in (we do
|
|
|
// not call Context.validate() like the ContextInterceptor)
|
|
|
if (context.getAuthentication() == null) {
|
|
|
- throw new AuthenticationCredentialsNotFoundException(
|
|
|
- "Authentication credentials were not found in the SecureContext");
|
|
|
+ credentialsNotFound("Authentication credentials were not found in the SecureContext",
|
|
|
+ object, attr);
|
|
|
}
|
|
|
|
|
|
// Attempt authentication
|
|
|
- Authentication authenticated = this.authenticationManager
|
|
|
- .authenticate(context.getAuthentication());
|
|
|
+ Authentication authenticated;
|
|
|
+
|
|
|
+ try {
|
|
|
+ authenticated = this.authenticationManager.authenticate(context
|
|
|
+ .getAuthentication());
|
|
|
+ } catch (AuthenticationException authenticationException) {
|
|
|
+ if (this.context != null) {
|
|
|
+ AuthenticationFailureEvent event = new AuthenticationFailureEvent(object,
|
|
|
+ attr, context.getAuthentication(),
|
|
|
+ authenticationException);
|
|
|
+ this.context.publishEvent(event);
|
|
|
+ }
|
|
|
+
|
|
|
+ throw authenticationException;
|
|
|
+ }
|
|
|
+
|
|
|
authenticated.setAuthenticated(true);
|
|
|
|
|
|
if (logger.isDebugEnabled()) {
|
|
@@ -301,12 +339,28 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
ContextHolder.setContext((Context) context);
|
|
|
|
|
|
// Attempt authorization
|
|
|
- this.accessDecisionManager.decide(authenticated, object, attr);
|
|
|
+ try {
|
|
|
+ this.accessDecisionManager.decide(authenticated, object, attr);
|
|
|
+ } catch (AccessDeniedException accessDeniedException) {
|
|
|
+ if (this.context != null) {
|
|
|
+ AuthorizationFailureEvent event = new AuthorizationFailureEvent(object,
|
|
|
+ attr, authenticated, accessDeniedException);
|
|
|
+ this.context.publishEvent(event);
|
|
|
+ }
|
|
|
+
|
|
|
+ throw accessDeniedException;
|
|
|
+ }
|
|
|
|
|
|
if (logger.isDebugEnabled()) {
|
|
|
logger.debug("Authorization successful");
|
|
|
}
|
|
|
|
|
|
+ if (this.context != null) {
|
|
|
+ AuthorizedEvent event = new AuthorizedEvent(object, attr,
|
|
|
+ authenticated);
|
|
|
+ this.context.publishEvent(event);
|
|
|
+ }
|
|
|
+
|
|
|
// Attempt to run as a different user
|
|
|
Authentication runAs = this.runAsManager.buildRunAs(authenticated,
|
|
|
object, attr);
|
|
@@ -337,6 +391,10 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
logger.debug("Public object - authentication not attempted");
|
|
|
}
|
|
|
|
|
|
+ if (this.context != null) {
|
|
|
+ this.context.publishEvent(new PublicInvocationEvent(object));
|
|
|
+ }
|
|
|
+
|
|
|
// Set Authentication object (if it exists) to be unauthenticated
|
|
|
if ((ContextHolder.getContext() != null)
|
|
|
&& ContextHolder.getContext() instanceof SecureContext) {
|
|
@@ -359,4 +417,29 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
return null; // no further work post-invocation
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Helper method which generates an exception contained the passed reason,
|
|
|
+ * and publishes an event to the application context.
|
|
|
+ *
|
|
|
+ * <P>
|
|
|
+ * Always throws an exception.
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param reason to be provided in the exceptiond detail
|
|
|
+ * @param secureObject that was being called
|
|
|
+ * @param configAttribs that were defined for the secureObject
|
|
|
+ */
|
|
|
+ private void credentialsNotFound(String reason, Object secureObject,
|
|
|
+ ConfigAttributeDefinition configAttribs) {
|
|
|
+ AuthenticationCredentialsNotFoundException exception = new AuthenticationCredentialsNotFoundException(reason);
|
|
|
+
|
|
|
+ if (this.context != null) {
|
|
|
+ AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(secureObject,
|
|
|
+ configAttribs, exception);
|
|
|
+ this.context.publishEvent(event);
|
|
|
+ }
|
|
|
+
|
|
|
+ throw exception;
|
|
|
+ }
|
|
|
}
|