Refactor MethodDefinitionMap to use Method, not MethodInvocation. Refactor AbstractSecurityInterceptor to not force use of Throwable. Move AOP Alliance based MethodSecurityInterceptor to separate package.
This commit is contained in:
parent
ba163d51ae
commit
992cf44b36
|
@ -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 (callback == null) {
|
||||
throw new IllegalArgumentException("Callback was null");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reverting to original Authentication: "
|
||||
+ token.getAuthenticated().toString());
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* 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;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
|
||||
/**
|
||||
* A return object received by {@link AbstractSecurityInterceptor} subclasses.
|
||||
*
|
||||
* <P>
|
||||
* This class reflects the status of the security interception, so that the
|
||||
* final call to <code>AbstractSecurityInterceptor</code> can tidy up
|
||||
* correctly.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* Whilst this class currently only wraps a single object, it has been modelled
|
||||
* as a class so that future changes to the operation of
|
||||
* <code>AbstractSecurityInterceptor</code> are abstracted from subclasses.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class InterceptorStatusToken {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private Authentication authenticated;
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public void setAuthenticated(Authentication authenticated) {
|
||||
this.authenticated = authenticated;
|
||||
}
|
||||
|
||||
public Authentication getAuthenticated() {
|
||||
return authenticated;
|
||||
}
|
||||
}
|
|
@ -1,50 +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;
|
||||
|
||||
/**
|
||||
* Allows the {@link AbstractSecurityInterceptor} to continue the secure object
|
||||
* invocation at the appropriate time.
|
||||
*
|
||||
* <P>
|
||||
* Concrete <code>AbstractSecurityInterceptor</code> subclasses are required to
|
||||
* provide a <code>SecurityInterceptorCallback</code>. This is called by the
|
||||
* <code>AbstractSecurityInterceptor</code> at the exact time the secure
|
||||
* object should have its processing continued. The exact way processing is
|
||||
* continued is specific to the type of secure object. For example, it may
|
||||
* involve proceeding with a method invocation, servicing a request, or
|
||||
* continuing a filter chain.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
* The result from processing the secure object should be returned to the
|
||||
* <code>AbstractSecurityInterceptor</code>, which in turn will ultimately
|
||||
* return it to the calling class.
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface SecurityInterceptorCallback {
|
||||
//~ Methods ================================================================
|
||||
|
||||
/**
|
||||
* Continues to process the secured object.
|
||||
*
|
||||
* @return the result (if any) from calling the secured object
|
||||
*/
|
||||
public Object proceedWithObject(Object object) throws Throwable;
|
||||
}
|
|
@ -22,6 +22,11 @@ import org.aopalliance.intercept.MethodInvocation;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.reflect.CodeSignature;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract implementation of <Code>MethodDefinitionSource</code>.
|
||||
|
@ -39,26 +44,55 @@ public abstract class AbstractMethodDefinitionSource
|
|||
|
||||
public ConfigAttributeDefinition getAttributes(Object object)
|
||||
throws IllegalArgumentException {
|
||||
if ((object == null) || !this.supports(object.getClass())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Object must be a MethodInvocation");
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException("Object cannot be null");
|
||||
}
|
||||
|
||||
return this.lookupAttributes((MethodInvocation) object);
|
||||
if (object instanceof MethodInvocation) {
|
||||
return this.lookupAttributes(((MethodInvocation) object).getMethod());
|
||||
}
|
||||
|
||||
if (object instanceof JoinPoint) {
|
||||
JoinPoint jp = (JoinPoint) object;
|
||||
Class targetClazz = jp.getTarget().getClass();
|
||||
String targetMethodName = jp.getStaticPart().getSignature().getName();
|
||||
Class[] types = ((CodeSignature) jp.getStaticPart().getSignature())
|
||||
.getParameterTypes();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Target Class: " + targetClazz);
|
||||
logger.debug("Target Method Name: " + targetMethodName);
|
||||
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Target Method Arg #" + i + ": "
|
||||
+ types[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return this.lookupAttributes(targetClazz.getMethod(
|
||||
targetMethodName, types));
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not obtain target method from JoinPoint: " + jp);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
"Object must be a MethodInvocation or JoinPoint");
|
||||
}
|
||||
|
||||
public boolean supports(Class clazz) {
|
||||
if (MethodInvocation.class.isAssignableFrom(clazz)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return (MethodInvocation.class.isAssignableFrom(clazz)
|
||||
|| JoinPoint.class.isAssignableFrom(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the actual lookup of the relevant
|
||||
* <code>ConfigAttributeDefinition</code> for the specified
|
||||
* <code>MethodInvocation</code>.
|
||||
* <code>Method</code> which is subject of the method invocation.
|
||||
*
|
||||
* <P>
|
||||
* Provided so subclasses need only to provide one basic method to properly
|
||||
|
@ -67,15 +101,14 @@ public abstract class AbstractMethodDefinitionSource
|
|||
*
|
||||
* <p>
|
||||
* Returns <code>null</code> if there are no matching attributes for the
|
||||
* method invocation.
|
||||
* method.
|
||||
* </p>
|
||||
*
|
||||
* @param mi the method being invoked for which configuration attributes
|
||||
* should be looked up
|
||||
* @param method the method being invoked for which configuration
|
||||
* attributes should be looked up
|
||||
*
|
||||
* @return the <code>ConfigAttributeDefinition</code> that applies to the
|
||||
* specified <code>MethodInvocation</code>
|
||||
* specified <code>Method</code>
|
||||
*/
|
||||
protected abstract ConfigAttributeDefinition lookupAttributes(
|
||||
MethodInvocation mi);
|
||||
protected abstract ConfigAttributeDefinition lookupAttributes(Method method);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ package net.sf.acegisecurity.intercept.method;
|
|||
import net.sf.acegisecurity.ConfigAttribute;
|
||||
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.metadata.Attributes;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -85,11 +83,10 @@ public class MethodDefinitionAttributes extends AbstractMethodDefinitionSource {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected ConfigAttributeDefinition lookupAttributes(
|
||||
MethodInvocation invocation) {
|
||||
protected ConfigAttributeDefinition lookupAttributes(Method method) {
|
||||
ConfigAttributeDefinition definition = new ConfigAttributeDefinition();
|
||||
|
||||
Class interceptedClass = invocation.getMethod().getDeclaringClass();
|
||||
Class interceptedClass = method.getDeclaringClass();
|
||||
|
||||
// add the class level attributes for the implementing class
|
||||
addClassAttributes(definition, interceptedClass);
|
||||
|
@ -98,10 +95,10 @@ public class MethodDefinitionAttributes extends AbstractMethodDefinitionSource {
|
|||
addClassAttributes(definition, interceptedClass.getInterfaces());
|
||||
|
||||
// add the method level attributes for the implemented method
|
||||
addMethodAttributes(definition, invocation.getMethod());
|
||||
addMethodAttributes(definition, method);
|
||||
|
||||
// add the method level attributes for the implemented intreface methods
|
||||
addInterfaceMethodAttributes(definition, invocation.getMethod());
|
||||
addInterfaceMethodAttributes(definition, method);
|
||||
|
||||
if (definition.size() == 0) {
|
||||
return null;
|
||||
|
|
|
@ -38,9 +38,9 @@ import java.util.Map;
|
|||
*
|
||||
* <p>
|
||||
* For consistency with {@link MethodDefinitionAttributes} as well as support
|
||||
* for {@link MethodDefinitionSourceAdvisor}, this implementation will return
|
||||
* a <code>ConfigAttributeDefinition</code> containing all configuration
|
||||
* attributes defined against:
|
||||
* for <code>MethodDefinitionSourceAdvisor</code>, this implementation will
|
||||
* return a <code>ConfigAttributeDefinition</code> containing all
|
||||
* configuration attributes defined against:
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
|
@ -83,8 +83,8 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource {
|
|||
/**
|
||||
* Obtains the configuration attributes explicitly defined against this
|
||||
* bean. This method will not return implicit configuration attributes
|
||||
* that may be returned by {@link #lookupAttributes(MethodInvocation)} as
|
||||
* it does not have access to a method invocation at this time.
|
||||
* that may be returned by {@link #lookupAttributes(Method)} as it does
|
||||
* not have access to a method invocation at this time.
|
||||
*
|
||||
* @return the attributes explicitly defined against this bean
|
||||
*/
|
||||
|
@ -95,9 +95,8 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource {
|
|||
/**
|
||||
* Obtains the number of configuration attributes explicitly defined
|
||||
* against this bean. This method will not return implicit configuration
|
||||
* attributes that may be returned by {@link
|
||||
* #lookupAttributes(MethodInvocation)} as it does not have access to a
|
||||
* method invocation at this time.
|
||||
* attributes that may be returned by {@link #lookupAttributes(Method)} as
|
||||
* it does not have access to a method invocation at this time.
|
||||
*
|
||||
* @return the number of configuration attributes explicitly defined
|
||||
* against this bean
|
||||
|
@ -209,25 +208,24 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource {
|
|||
}
|
||||
}
|
||||
|
||||
protected ConfigAttributeDefinition lookupAttributes(MethodInvocation mi) {
|
||||
protected ConfigAttributeDefinition lookupAttributes(Method method) {
|
||||
ConfigAttributeDefinition definition = new ConfigAttributeDefinition();
|
||||
|
||||
// Add attributes explictly defined for this method invocation
|
||||
ConfigAttributeDefinition directlyAssigned = (ConfigAttributeDefinition) this.methodMap
|
||||
.get(mi.getMethod());
|
||||
.get(method);
|
||||
merge(definition, directlyAssigned);
|
||||
|
||||
// Add attributes explicitly defined for this method invocation's interfaces
|
||||
Class[] interfaces = mi.getMethod().getDeclaringClass().getInterfaces();
|
||||
Class[] interfaces = method.getDeclaringClass().getInterfaces();
|
||||
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
Class clazz = interfaces[i];
|
||||
|
||||
try {
|
||||
// Look for the method on the current interface
|
||||
Method interfaceMethod = clazz.getDeclaredMethod(mi.getMethod()
|
||||
.getName(),
|
||||
mi.getMethod().getParameterTypes());
|
||||
Method interfaceMethod = clazz.getDeclaredMethod(method.getName(),
|
||||
method.getParameterTypes());
|
||||
ConfigAttributeDefinition interfaceAssigned = (ConfigAttributeDefinition) this.methodMap
|
||||
.get(interfaceMethod);
|
||||
merge(definition, interfaceAssigned);
|
||||
|
|
|
@ -20,8 +20,7 @@ import net.sf.acegisecurity.intercept.ObjectDefinitionSource;
|
|||
|
||||
/**
|
||||
* Marker interface for <code>ObjectDefinitionSource</code> implementations
|
||||
* that are designed to perform lookups keyed on
|
||||
* <code>MethodInvocation</code>s.
|
||||
* that are designed to perform lookups keyed on <code>Method</code>s.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.sf.acegisecurity.intercept.method;
|
||||
package net.sf.acegisecurity.intercept.method.aopalliance;
|
||||
|
||||
import net.sf.acegisecurity.intercept.method.MethodDefinitionSource;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
|
@ -46,7 +48,7 @@ import java.lang.reflect.Method;
|
|||
* <p>
|
||||
* Based on Spring's TransactionAttributeSourceAdvisor.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
|
@ -13,22 +13,26 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.sf.acegisecurity.intercept.method;
|
||||
package net.sf.acegisecurity.intercept.method.aopalliance;
|
||||
|
||||
import net.sf.acegisecurity.intercept.AbstractSecurityInterceptor;
|
||||
import net.sf.acegisecurity.intercept.InterceptorStatusToken;
|
||||
import net.sf.acegisecurity.intercept.ObjectDefinitionSource;
|
||||
import net.sf.acegisecurity.intercept.SecurityInterceptorCallback;
|
||||
import net.sf.acegisecurity.intercept.method.MethodDefinitionSource;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
|
||||
/**
|
||||
* Provides security interception of method invocations.
|
||||
* Provides security interception of AOP Alliance based method invocations.
|
||||
*
|
||||
* <p>
|
||||
* The <code>ObjectDefinitionSource</code> required by this security
|
||||
* interceptor is of type {@link MethodDefinitionSource}.
|
||||
* interceptor is of type {@link MethodDefinitionSource}. This is shared with
|
||||
* the AspectJ based security interceptor
|
||||
* (<code>AspectJSecurityInterceptor</code>), since both work with Java
|
||||
* <code>Method</code>s.
|
||||
* </p>
|
||||
*
|
||||
* <P>
|
||||
|
@ -39,7 +43,7 @@ import org.aopalliance.intercept.MethodInvocation;
|
|||
* @version $Id$
|
||||
*/
|
||||
public class MethodSecurityInterceptor extends AbstractSecurityInterceptor
|
||||
implements MethodInterceptor, SecurityInterceptorCallback {
|
||||
implements MethodInterceptor {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private MethodDefinitionSource objectDefinitionSource;
|
||||
|
@ -79,14 +83,19 @@ public class MethodSecurityInterceptor extends AbstractSecurityInterceptor
|
|||
* @throws Throwable if any error occurs
|
||||
*/
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
return super.interceptor(mi, this);
|
||||
Object result;
|
||||
InterceptorStatusToken token = super.beforeInvocation(mi);
|
||||
|
||||
try {
|
||||
result = mi.proceed();
|
||||
} finally {
|
||||
super.afterInvocation(token);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public ObjectDefinitionSource obtainObjectDefinitionSource() {
|
||||
return this.objectDefinitionSource;
|
||||
}
|
||||
|
||||
public Object proceedWithObject(Object object) throws Throwable {
|
||||
return ((MethodInvocation) object).proceed();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<html>
|
||||
<body>
|
||||
Enforces security for AOP Alliance <code>MethodInvocation</code>s, such as via
|
||||
Spring AOP.
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +1,6 @@
|
|||
<html>
|
||||
<body>
|
||||
Enforces security for <code>MethodInvocation</code>s, such as via
|
||||
Spring AOP.
|
||||
Provides support objects for securing Java method invocations
|
||||
via different AOP libraries.
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
package net.sf.acegisecurity.intercept.web;
|
||||
|
||||
import net.sf.acegisecurity.intercept.AbstractSecurityInterceptor;
|
||||
import net.sf.acegisecurity.intercept.InterceptorStatusToken;
|
||||
import net.sf.acegisecurity.intercept.ObjectDefinitionSource;
|
||||
import net.sf.acegisecurity.intercept.SecurityInterceptorCallback;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -43,8 +43,7 @@ import net.sf.acegisecurity.intercept.SecurityInterceptorCallback;
|
|||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class FilterSecurityInterceptor extends AbstractSecurityInterceptor
|
||||
implements SecurityInterceptorCallback {
|
||||
public class FilterSecurityInterceptor extends AbstractSecurityInterceptor {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private FilterInvocationDefinitionSource objectDefinitionSource;
|
||||
|
@ -75,17 +74,16 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor
|
|||
}
|
||||
|
||||
public void invoke(FilterInvocation fi) throws Throwable {
|
||||
super.interceptor(fi, this);
|
||||
InterceptorStatusToken token = super.beforeInvocation(fi);
|
||||
|
||||
try {
|
||||
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
|
||||
} finally {
|
||||
super.afterInvocation(token);
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectDefinitionSource obtainObjectDefinitionSource() {
|
||||
return this.objectDefinitionSource;
|
||||
}
|
||||
|
||||
public Object proceedWithObject(Object object) throws Throwable {
|
||||
FilterInvocation fi = (FilterInvocation) object;
|
||||
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ public class MethodDefinitionAttributesTests extends TestCase {
|
|||
"attributes");
|
||||
|
||||
p.setProperty(PREFIX + "securityInterceptor.class",
|
||||
"net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor");
|
||||
"net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor");
|
||||
p.setProperty(PREFIX + "securityInterceptor.authenticationManager(ref)",
|
||||
"authentication");
|
||||
p.setProperty(PREFIX + "securityInterceptor.accessDecisionManager(ref)",
|
||||
|
|
|
@ -18,7 +18,7 @@ package net.sf.acegisecurity.intercept.method;
|
|||
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
||||
import net.sf.acegisecurity.SecurityConfig;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -82,7 +82,7 @@ public class MockMethodDefinitionSource extends AbstractMethodDefinitionSource {
|
|||
}
|
||||
}
|
||||
|
||||
protected ConfigAttributeDefinition lookupAttributes(MethodInvocation mi) {
|
||||
protected ConfigAttributeDefinition lookupAttributes(Method method) {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.sf.acegisecurity.intercept.method;
|
||||
package net.sf.acegisecurity.intercept.method.aopalliance;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import net.sf.acegisecurity.TargetObject;
|
||||
import net.sf.acegisecurity.intercept.method.MethodDefinitionMap;
|
||||
import net.sf.acegisecurity.intercept.method.MethodDefinitionSourceEditor;
|
||||
|
||||
import org.springframework.aop.framework.AopConfigException;
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.sf.acegisecurity.intercept.method;
|
||||
package net.sf.acegisecurity.intercept.method.aopalliance;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
@ -28,21 +28,23 @@ import net.sf.acegisecurity.GrantedAuthorityImpl;
|
|||
import net.sf.acegisecurity.ITargetObject;
|
||||
import net.sf.acegisecurity.MockAccessDecisionManager;
|
||||
import net.sf.acegisecurity.MockAuthenticationManager;
|
||||
import net.sf.acegisecurity.MockMethodInvocation;
|
||||
import net.sf.acegisecurity.MockRunAsManager;
|
||||
import net.sf.acegisecurity.RunAsManager;
|
||||
import net.sf.acegisecurity.context.ContextHolder;
|
||||
import net.sf.acegisecurity.context.ContextImpl;
|
||||
import net.sf.acegisecurity.context.SecureContext;
|
||||
import net.sf.acegisecurity.context.SecureContextImpl;
|
||||
import net.sf.acegisecurity.intercept.SecurityInterceptorCallback;
|
||||
import net.sf.acegisecurity.intercept.method.AbstractMethodDefinitionSource;
|
||||
import net.sf.acegisecurity.intercept.method.MockMethodDefinitionSource;
|
||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import net.sf.acegisecurity.runas.RunAsManagerImpl;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
|
@ -250,25 +252,13 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testRejectsCallsWhenCallbackIsNull() throws Throwable {
|
||||
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
|
||||
|
||||
try {
|
||||
interceptor.interceptor(new Object(), null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("Callback was null", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject()
|
||||
throws Throwable {
|
||||
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
|
||||
interceptor.setObjectDefinitionSource(new MockObjectDefinitionSourceWhichOnlySupportsStrings());
|
||||
|
||||
try {
|
||||
interceptor.interceptor(new Integer(1),
|
||||
new MockSecurityInterceptorCallback());
|
||||
interceptor.invoke(new MockMethodInvocation());
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(expected.getMessage().startsWith("ObjectDefinitionSource does not support objects of type"));
|
||||
|
@ -279,7 +269,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
|
||||
|
||||
try {
|
||||
interceptor.interceptor(null, new MockSecurityInterceptorCallback());
|
||||
interceptor.invoke(null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("Object was null", expected.getMessage());
|
||||
|
@ -420,7 +410,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||
"net.sf.acegisecurity.MockRunAsManager");
|
||||
|
||||
p.setProperty(PREFIX + "securityInterceptor.class",
|
||||
"net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor");
|
||||
"net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor");
|
||||
p.setProperty(PREFIX + "securityInterceptor.authenticationManager(ref)",
|
||||
"authentication");
|
||||
p.setProperty(PREFIX + "securityInterceptor.accessDecisionManager(ref)",
|
||||
|
@ -482,8 +472,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
protected ConfigAttributeDefinition lookupAttributes(
|
||||
MethodInvocation mi) {
|
||||
protected ConfigAttributeDefinition lookupAttributes(Method method) {
|
||||
throw new UnsupportedOperationException(
|
||||
"mock method not implemented");
|
||||
}
|
||||
|
@ -509,13 +498,4 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class MockSecurityInterceptorCallback
|
||||
implements SecurityInterceptorCallback {
|
||||
public Object proceedWithObject(Object object)
|
||||
throws Throwable {
|
||||
throw new UnsupportedOperationException(
|
||||
"mock method not implemented");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@
|
|||
</bean>
|
||||
|
||||
<!-- We don't validate config attributes, as it's unsupported by MethodDefinitionAttributes -->
|
||||
<bean id="securityInterceptor" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
|
||||
<bean id="securityInterceptor" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="validateConfigAttributes"><value>false</value></property>
|
||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref local="accessDecisionManager"/></property>
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
<!-- ===================== SECURITY DEFINITIONS ======================= -->
|
||||
|
||||
<bean id="publicContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
|
||||
<bean id="publicContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property>
|
||||
<property name="runAsManager"><ref local="runAsManager"/></property>
|
||||
|
@ -97,7 +97,7 @@
|
|||
</bean>
|
||||
|
||||
<!-- We expect all callers of the backend object to hold the role ROLE_RUN_AS_SERVER -->
|
||||
<bean id="backendContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
|
||||
<bean id="backendContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property>
|
||||
<property name="runAsManager"><ref local="runAsManager"/></property>
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
|
||||
<!-- ===================== SECURITY DEFINITIONS ======================= -->
|
||||
|
||||
<bean id="publicContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
|
||||
<bean id="publicContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property>
|
||||
<property name="runAsManager"><ref local="runAsManager"/></property>
|
||||
|
@ -119,7 +119,7 @@
|
|||
</bean>
|
||||
|
||||
<!-- We expect all callers of the backend object to hold the role ROLE_RUN_AS_SERVER -->
|
||||
<bean id="backendContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
|
||||
<bean id="backendContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property>
|
||||
<property name="runAsManager"><ref local="runAsManager"/></property>
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
|
||||
<!-- ===================== SECURITY DEFINITIONS ======================= -->
|
||||
|
||||
<bean id="publicContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
|
||||
<bean id="publicContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property>
|
||||
<property name="runAsManager"><ref local="runAsManager"/></property>
|
||||
|
@ -108,7 +108,7 @@
|
|||
</bean>
|
||||
|
||||
<!-- We expect all callers of the backend object to hold the role ROLE_RUN_AS_SERVER -->
|
||||
<bean id="backendContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
|
||||
<bean id="backendContactManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager"><ref local="authenticationManager"/></property>
|
||||
<property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property>
|
||||
<property name="runAsManager"><ref local="runAsManager"/></property>
|
||||
|
|
Loading…
Reference in New Issue