|
@@ -76,8 +76,16 @@ import java.util.Set;
|
|
|
* Perform any run-as replacement via the configured {@link RunAsManager}.
|
|
|
* </li>
|
|
|
* <li>
|
|
|
- * Perform a callback to the {@link SecurityInterceptorCallback}, which will
|
|
|
- * actually proceed with executing the object.
|
|
|
+ * Pass control back to the concrete subclass, which will actually proceed with
|
|
|
+ * executing the object. A {@link InterceptorStatusToken} is returned so that
|
|
|
+ * after the subclass has finished proceeding with execution of the object,
|
|
|
+ * its finally clause can ensure the <code>AbstractSecurityInterceptor</code>
|
|
|
+ * is re-called and tidies up correctly.
|
|
|
+ * </li>
|
|
|
+ * <li>
|
|
|
+ * The concrete subclass will re-call the
|
|
|
+ * <code>AbstractSecurityInterceptor</code> via the {@link
|
|
|
+ * #afterInvocation(InterceptorStatusToken)} method.
|
|
|
* </li>
|
|
|
* <li>
|
|
|
* If the <code>RunAsManager</code> replaced the <code>Authentication</code>
|
|
@@ -98,17 +106,20 @@ import java.util.Set;
|
|
|
* object to false.
|
|
|
* </li>
|
|
|
* <li>
|
|
|
- * Perform a callback to the {@link SecurityInterceptorCallback}, which will
|
|
|
- * actually proceed with the invocation.
|
|
|
+ * As described above, the concrete subclass will be returned an
|
|
|
+ * <code>InterceptorStatusToken</code> which is subsequently re-presented to
|
|
|
+ * the <code>AbstractSecurityInterceptor</code> after the secure object has
|
|
|
+ * been executed. The <code>AbstractSecurityInterceptor</code> will take no
|
|
|
+ * further action when its {@link #afterInvocation(InterceptorStatusToken)} is
|
|
|
+ * called.
|
|
|
* </li>
|
|
|
* </ol>
|
|
|
*
|
|
|
* </li>
|
|
|
* <li>
|
|
|
- * Return the result from the <code>SecurityInterceptorCallback</code> to the
|
|
|
- * method that called {@link AbstractSecurityInterceptor#interceptor(Object,
|
|
|
- * SecurityInterceptorCallback)}. This is almost always a concrete subclass of
|
|
|
- * the <code>AbstractSecurityInterceptor</code>.
|
|
|
+ * Control again returns to the concrete subclass, which will return to the
|
|
|
+ * caller any result or exception that occurred when it proceeded with the
|
|
|
+ * execution of the secure object.
|
|
|
* </li>
|
|
|
* </ol>
|
|
|
* </p>
|
|
@@ -226,37 +237,24 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Does the work of authenticating and authorizing the request.
|
|
|
- *
|
|
|
- * <P>
|
|
|
- * Throws {@link net.sf.acegisecurity.AcegiSecurityException} and its
|
|
|
- * subclasses.
|
|
|
- * </p>
|
|
|
- *
|
|
|
- * @param object details of a secure object invocation
|
|
|
- * @param callback the object that will complete the target secure object
|
|
|
- * invocation
|
|
|
- *
|
|
|
- * @return The value that was returned by the
|
|
|
- * <code>SecurityInterceptorCallback</code>
|
|
|
- *
|
|
|
- * @throws Throwable if any error occurs during the
|
|
|
- * <code>SecurityInterceptorCallback</code>
|
|
|
- * @throws IllegalArgumentException if a required argument was missing or
|
|
|
- * invalid
|
|
|
- * @throws AuthenticationCredentialsNotFoundException if the
|
|
|
- * <code>ContextHolder</code> is not populated with a valid
|
|
|
- * <code>SecureContext</code>
|
|
|
- */
|
|
|
- public Object interceptor(Object object,
|
|
|
- SecurityInterceptorCallback callback) throws Throwable {
|
|
|
- if (object == null) {
|
|
|
- throw new IllegalArgumentException("Object was null");
|
|
|
+ protected void afterInvocation(InterceptorStatusToken token) {
|
|
|
+ if (token == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.debug("Reverting to original Authentication: "
|
|
|
+ + token.getAuthenticated().toString());
|
|
|
}
|
|
|
|
|
|
- if (callback == null) {
|
|
|
- throw new IllegalArgumentException("Callback was null");
|
|
|
+ SecureContext secureContext = (SecureContext) ContextHolder.getContext();
|
|
|
+ secureContext.setAuthentication(token.getAuthenticated());
|
|
|
+ ContextHolder.setContext(secureContext);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected InterceptorStatusToken beforeInvocation(Object object) {
|
|
|
+ if (object == null) {
|
|
|
+ throw new IllegalArgumentException("Object was null");
|
|
|
}
|
|
|
|
|
|
if (!this.obtainObjectDefinitionSource().supports(object.getClass())) {
|
|
@@ -294,7 +292,11 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
Authentication authenticated = this.authenticationManager
|
|
|
.authenticate(context.getAuthentication());
|
|
|
authenticated.setAuthenticated(true);
|
|
|
- logger.debug("Authenticated: " + authenticated.toString());
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.debug("Authenticated: " + authenticated.toString());
|
|
|
+ }
|
|
|
+
|
|
|
context.setAuthentication(authenticated);
|
|
|
ContextHolder.setContext((Context) context);
|
|
|
|
|
@@ -315,31 +317,20 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
"RunAsManager did not change Authentication object");
|
|
|
}
|
|
|
|
|
|
- return callback.proceedWithObject(object);
|
|
|
+ return null; // no further work post-invocation
|
|
|
} else {
|
|
|
if (logger.isDebugEnabled()) {
|
|
|
logger.debug("Switching to RunAs Authentication: "
|
|
|
+ runAs.toString());
|
|
|
}
|
|
|
|
|
|
- SecureContext origSecureContext = null;
|
|
|
+ context.setAuthentication(runAs);
|
|
|
+ ContextHolder.setContext((Context) context);
|
|
|
|
|
|
- try {
|
|
|
- origSecureContext = (SecureContext) ContextHolder
|
|
|
- .getContext();
|
|
|
- context.setAuthentication(runAs);
|
|
|
- ContextHolder.setContext((Context) context);
|
|
|
+ InterceptorStatusToken token = new InterceptorStatusToken();
|
|
|
+ token.setAuthenticated(authenticated);
|
|
|
|
|
|
- return callback.proceedWithObject(object);
|
|
|
- } finally {
|
|
|
- if (logger.isDebugEnabled()) {
|
|
|
- logger.debug("Reverting to original Authentication: "
|
|
|
- + authenticated.toString());
|
|
|
- }
|
|
|
-
|
|
|
- origSecureContext.setAuthentication(authenticated);
|
|
|
- ContextHolder.setContext(origSecureContext);
|
|
|
- }
|
|
|
+ return token; // revert to token.Authenticated post-invocation
|
|
|
}
|
|
|
} else {
|
|
|
if (logger.isDebugEnabled()) {
|
|
@@ -365,7 +356,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return callback.proceedWithObject(object);
|
|
|
+ return null; // no further work post-invocation
|
|
|
}
|
|
|
}
|
|
|
}
|