From 3ece12c3868cc23411786e839a7e2646546dbdd3 Mon Sep 17 00:00:00 2001
From: Ben Alex
- * This class will only detect those attributes which are defined for the:
- *
- *
- *
- *
- * Note that attributes defined against parent classes (either for their - * methods or interfaces) are not detected. The attributes must be defined - * against an explicit method or interface on the intercepted class. - *
- * - *- * Attributes detected that do not implement {@link ConfigAttribute} will be - * ignored. - *
- * - * @author Cameron Braid - * @author Ben Alex - * @version $Id$ - */ -public class MethodDefinitionAttributes implements MethodDefinitionSource { - //~ Instance fields ======================================================== - - private Attributes attributes; - - //~ Methods ================================================================ - - public void setAttributes(Attributes attributes) { - this.attributes = attributes; - } - - public ConfigAttributeDefinition getAttributes(MethodInvocation invocation) { - ConfigAttributeDefinition definition = new ConfigAttributeDefinition(); - - Class interceptedClass = invocation.getMethod().getDeclaringClass(); - - // add the class level attributes for the implementing class - addClassAttributes(definition, interceptedClass); - - // add the class level attributes for the implemented interfaces - addClassAttributes(definition, interceptedClass.getInterfaces()); - - // add the method level attributes for the implemented method - addMethodAttributes(definition, invocation.getMethod()); - - // add the method level attributes for the implemented intreface methods - addInterfaceMethodAttributes(definition, invocation.getMethod()); - - return definition; - } - - public Iterator getConfigAttributeDefinitions() { - return null; - } - - private void add(ConfigAttributeDefinition definition, Collection attribs) { - for (Iterator iter = attribs.iterator(); iter.hasNext();) { - Object o = (Object) iter.next(); - - if (o instanceof ConfigAttribute) { - definition.addConfigAttribute((ConfigAttribute) o); - } - } - } - - private void addClassAttributes(ConfigAttributeDefinition definition, - Class clazz) { - addClassAttributes(definition, new Class[] {clazz}); - } - - private void addClassAttributes(ConfigAttributeDefinition definition, - Class[] clazz) { - for (int i = 0; i < clazz.length; i++) { - Collection classAttributes = attributes.getAttributes(clazz[i]); - - if (classAttributes != null) { - add(definition, classAttributes); - } - } - } - - private void addInterfaceMethodAttributes( - ConfigAttributeDefinition definition, Method method) { - Class[] interfaces = method.getDeclaringClass().getInterfaces(); - - for (int i = 0; i < interfaces.length; i++) { - Class clazz = interfaces[i]; - - try { - Method m = clazz.getDeclaredMethod(method.getName(), - method.getParameterTypes()); - addMethodAttributes(definition, m); - } catch (Exception e) { - // this won't happen since we are getting a method from an interface that - // the declaring class implements - } - } - } - - private void addMethodAttributes(ConfigAttributeDefinition definition, - Method method) { - // add the method level attributes - Collection methodAttributes = attributes.getAttributes(method); - - if (methodAttributes != null) { - add(definition, methodAttributes); - } - } -} diff --git a/core/src/main/java/org/acegisecurity/MethodDefinitionMap.java b/core/src/main/java/org/acegisecurity/MethodDefinitionMap.java deleted file mode 100644 index 940bb8e8ce..0000000000 --- a/core/src/main/java/org/acegisecurity/MethodDefinitionMap.java +++ /dev/null @@ -1,175 +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; - -import org.aopalliance.intercept.MethodInvocation; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.lang.reflect.Method; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - - -/** - * Stores a {@link ConfigAttributeDefinition} for each method signature defined - * in a bean context. - * - * @author Ben Alex - * @version $Id$ - */ -public class MethodDefinitionMap implements MethodDefinitionSource { - private static final Log logger = LogFactory.getLog(MethodDefinitionMap.class); - - /** Map from Method to ApplicationDefinition */ - protected Map methodMap = new HashMap(); - - /** Map from Method to name pattern used for registration */ - private Map nameMap = new HashMap(); - - public ConfigAttributeDefinition getAttributes(MethodInvocation invocation) { - return (ConfigAttributeDefinition) this.methodMap.get(invocation.getMethod()); - } - - public Iterator getConfigAttributeDefinitions() { - return methodMap.values().iterator(); - } - - public int getMethodMapSize() { - return this.methodMap.size(); - } - - /** - * Add required authorities for a secure method. Method names can end or - * start with "" for matching multiple methods. - * - * @param method the method to be secured - * @param attr required authorities associated with the method - */ - public void addSecureMethod(Method method, ConfigAttributeDefinition attr) { - logger.info("Adding secure method [" + method + "] with attributes [" + - attr + "]"); - this.methodMap.put(method, attr); - } - - /** - * Add required authorities for a secure method. Method names can end or - * start with "" for matching multiple methods. - * - * @param name class and method name, separated by a dot - * @param attr required authorities associated with the method - * - * @throws IllegalArgumentException DOCUMENT ME! - */ - public void addSecureMethod(String name, ConfigAttributeDefinition attr) { - int lastDotIndex = name.lastIndexOf("."); - - if (lastDotIndex == -1) { - throw new IllegalArgumentException("'" + name + - "' is not a valid method name: format is FQN.methodName"); - } - - String className = name.substring(0, lastDotIndex); - String methodName = name.substring(lastDotIndex + 1); - - try { - Class clazz = Class.forName(className, true, - Thread.currentThread().getContextClassLoader()); - addSecureMethod(clazz, methodName, attr); - } catch (ClassNotFoundException ex) { - throw new IllegalArgumentException("Class '" + className + - "' not found"); - } - } - - /** - * Add required authorities for a secure method. Method names can end or - * start with "" for matching multiple methods. - * - * @param clazz target interface or class - * @param mappedName mapped method name - * @param attr required authorities associated with the method - * - * @throws IllegalArgumentException DOCUMENT ME! - */ - public void addSecureMethod(Class clazz, String mappedName, - ConfigAttributeDefinition attr) { - String name = clazz.getName() + '.' + mappedName; - - logger.debug("Adding secure method [" + name + "] with attributes [" + - attr + "]"); - - Method[] methods = clazz.getDeclaredMethods(); - List matchingMethods = new ArrayList(); - - for (int i = 0; i < methods.length; i++) { - if (methods[i].getName().equals(mappedName) || - isMatch(methods[i].getName(), mappedName)) { - matchingMethods.add(methods[i]); - } - } - - if (matchingMethods.isEmpty()) { - throw new IllegalArgumentException("Couldn't find method '" + - mappedName + "' on " + clazz); - } - - // register all matching methods - for (Iterator it = matchingMethods.iterator(); it.hasNext();) { - Method method = (Method) it.next(); - String regMethodName = (String) this.nameMap.get(method); - - if ((regMethodName == null) || - (!regMethodName.equals(name) && - (regMethodName.length() <= name.length()))) { - // no already registered method name, or more specific - // method name specification now -> (re-)register method - if (regMethodName != null) { - logger.debug("Replacing attributes for secure method [" + - method + "]: current name [" + name + - "] is more specific than [" + regMethodName + "]"); - } - - this.nameMap.put(method, name); - addSecureMethod(method, attr); - } else { - logger.debug("Keeping attributes for secure method [" + method + - "]: current name [" + name + - "] is not more specific than [" + regMethodName + "]"); - } - } - } - - /** - * Return if the given method name matches the mapped name. The default - * implementation checks for "xxx" and "xxx" matches. - * - * @param methodName the method name of the class - * @param mappedName the name in the descriptor - * - * @return if the names match - */ - private boolean isMatch(String methodName, String mappedName) { - return (mappedName.endsWith("*") && - methodName.startsWith(mappedName.substring(0, mappedName.length() - 1))) || - (mappedName.startsWith("*") && - methodName.endsWith(mappedName.substring(1, mappedName.length()))); - } -} diff --git a/core/src/main/java/org/acegisecurity/MethodDefinitionSource.java b/core/src/main/java/org/acegisecurity/MethodDefinitionSource.java deleted file mode 100644 index 63b4b50974..0000000000 --- a/core/src/main/java/org/acegisecurity/MethodDefinitionSource.java +++ /dev/null @@ -1,52 +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; - -import org.aopalliance.intercept.MethodInvocation; - -import java.util.Iterator; - - -/** - * Implemented by classes that store {@link ConfigAttributeDefinition}s and can - * identify the appropriateConfigAttributeDefinition
that
- * applies for the current method call.
- *
- * @author Ben Alex
- * @version $Id$
- */
-public interface MethodDefinitionSource {
- //~ Methods ================================================================
-
- /**
- * DOCUMENT ME!
- *
- * @param invocation the method being called
- *
- * @return the ConfigAttributeDefinition
that applies to the
- * passed method call
- */
- public ConfigAttributeDefinition getAttributes(MethodInvocation invocation);
-
- /**
- * If available, all of the ConfigAttributeDefinition
s defined
- * by the implementing class.
- *
- * @return an iterator over all the ConfigAttributeDefinition
s
- * or null
if unsupported
- */
- public Iterator getConfigAttributeDefinitions();
-}
diff --git a/core/src/main/java/org/acegisecurity/MethodDefinitionSourceEditor.java b/core/src/main/java/org/acegisecurity/MethodDefinitionSourceEditor.java
deleted file mode 100644
index 88dbf33851..0000000000
--- a/core/src/main/java/org/acegisecurity/MethodDefinitionSourceEditor.java
+++ /dev/null
@@ -1,78 +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;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.beans.propertyeditors.PropertiesEditor;
-
-import java.beans.PropertyEditorSupport;
-
-import java.util.Iterator;
-import java.util.Properties;
-
-
-/**
- * Property editor to assist with the setup of {@link MethodDefinitionSource}.
- *
- * - * The class creates and populates an {@link MethodDefinitionMap}. - *
- * - * @author Ben Alex - * @version $Id$ - */ -public class MethodDefinitionSourceEditor extends PropertyEditorSupport { - //~ Static fields/initializers ============================================= - - private static final Log logger = LogFactory.getLog(MethodDefinitionSourceEditor.class); - - //~ Methods ================================================================ - - public void setAsText(String s) throws IllegalArgumentException { - MethodDefinitionMap source = new MethodDefinitionMap(); - - if ((s == null) || "".equals(s)) { - // Leave value in property editor null - } else { - // Use properties editor to tokenize the string - PropertiesEditor propertiesEditor = new PropertiesEditor(); - propertiesEditor.setAsText(s); - - Properties props = (Properties) propertiesEditor.getValue(); - - // Now we have properties, process each one individually - ConfigAttributeEditor configAttribEd = new ConfigAttributeEditor(); - - for (Iterator iter = props.keySet().iterator(); iter.hasNext();) { - String name = (String) iter.next(); - String value = props.getProperty(name); - - // Convert value to series of security configuration attributes - configAttribEd.setAsText(value); - - ConfigAttributeDefinition attr = (ConfigAttributeDefinition) configAttribEd - .getValue(); - - // Register name and attribute - source.addSecureMethod(name, attr); - } - } - - setValue(source); - } -} diff --git a/core/src/main/java/org/acegisecurity/SecurityInterceptor.java b/core/src/main/java/org/acegisecurity/SecurityInterceptor.java deleted file mode 100644 index f61f3fab24..0000000000 --- a/core/src/main/java/org/acegisecurity/SecurityInterceptor.java +++ /dev/null @@ -1,317 +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; - -import net.sf.acegisecurity.context.Context; -import net.sf.acegisecurity.context.ContextHolder; -import net.sf.acegisecurity.context.SecureContext; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.InitializingBean; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - - -/** - * Intercepts calls to an object and applies security. - * - *
- * A method is treated as public unless it has one or more configuration
- * attributes defined via {@link
- * #setMethodDefinitionSource(MethodDefinitionSource)}. If public, no
- * authentication will be attempted, which means an unauthenticated {@link
- * Authentication} object may be present in the {@link ContextHolder} (if any
- * such an unauthenticated Authentication
object exists, its
- * {@link Authentication#isAuthenticated()} method will return
- * false
once the SecurityInterceptor
has
- * intercepted the public method).
- *
- * For those methods to be secured by the interceptor, one or more - * configuration attributes must be defined. These attributes are stored as - * {@link ConfigAttribute} objects. - *
- * - *
- * The presence of a configuration attribute for a given method will force
- * authentication to be attempted via the {@link AuthenticationManager}
- * configured against the interceptor. If successfully authenticated, the
- * configured {@link AccessDecisionManager} will be passed the {@link
- * ConfigAttributeDefinition} applicable for the method invocation, the
- * method invocation itself, and the Authentication
object. The
- * AccessDecisionManager
which will then make the authorization
- * decision.
- *
- * There shouldn't be any requirement to customise the behaviour of the
- * SecurityInterceptor
, as all security decisions are made by the
- * AuthenticationProvider
and AccessDecisionManager
- * interfaces, which can of course be replaced with different concrete
- * implementations.
- *
ContextHolder
does not contain a valid
- * SecureContext
which in turn contains an
- * Authentication
object
- */
- public Object invoke(MethodInvocation mi) throws Throwable {
- if (logger.isDebugEnabled()) {
- logger.debug("Intercepted request for method " + mi.getMethod());
- }
-
- ConfigAttributeDefinition attr = this.methodDefinitionSource
- .getAttributes(mi);
-
- if (attr != null) {
- if (logger.isDebugEnabled()) {
- logger.debug("Secure method configuration "
- + attr.getConfigAttributes().toString());
- }
-
- // 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");
- }
-
- SecureContext context = (SecureContext) ContextHolder.getContext();
-
- // 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");
- }
-
- // Attempt authentication
- Authentication authenticated = this.authenticationManager
- .authenticate(context.getAuthentication());
- authenticated.setAuthenticated(true);
- logger.debug("Authenticated: " + authenticated.toString());
- context.setAuthentication(authenticated);
- ContextHolder.setContext((Context) context);
-
- // Attempt authorization
- this.accessDecisionManager.decide(authenticated, mi, attr);
-
- if (logger.isDebugEnabled()) {
- logger.debug("Authorization successful");
- }
-
- // Attempt to run as a different user
- Authentication runAs = this.runAsManager.buildRunAs(authenticated,
- mi, attr);
-
- if (runAs == null) {
- if (logger.isDebugEnabled()) {
- logger.debug(
- "RunAsManager did not change Authentication object");
- }
-
- Object ret = mi.proceed();
-
- return ret;
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Switching to RunAs Authentication: "
- + runAs.toString());
- }
-
- context.setAuthentication(runAs);
- ContextHolder.setContext((Context) context);
-
- Object ret = mi.proceed();
-
- if (logger.isDebugEnabled()) {
- logger.debug("Reverting to original Authentication: "
- + authenticated.toString());
- }
-
- context.setAuthentication(authenticated);
- ContextHolder.setContext((Context) context);
-
- return ret;
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Public method - authentication not attempted");
- }
-
- // Set Authentication object (if it exists) to be unauthenticated
- if ((ContextHolder.getContext() != null)
- && ContextHolder.getContext() instanceof SecureContext) {
- SecureContext context = (SecureContext) ContextHolder
- .getContext();
-
- if (context.getAuthentication() != null) {
- if (logger.isDebugEnabled()) {
- logger.debug(
- "Authentication object detected and tagged as unauthenticated");
- }
-
- Authentication authenticated = context.getAuthentication();
- authenticated.setAuthenticated(false);
- context.setAuthentication(authenticated);
- ContextHolder.setContext((Context) context);
- }
- }
-
- Object ret = mi.proceed();
-
- return ret;
- }
- }
-}