From 3ece12c3868cc23411786e839a7e2646546dbdd3 Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Fri, 2 Apr 2004 12:03:18 +0000 Subject: [PATCH] Moved to net.sf.acegisecurity.intercept.method. --- .../MethodDefinitionAttributes.java | 158 --------- .../acegisecurity/MethodDefinitionMap.java | 175 ---------- .../acegisecurity/MethodDefinitionSource.java | 52 --- .../MethodDefinitionSourceEditor.java | 78 ----- .../acegisecurity/SecurityInterceptor.java | 317 ------------------ 5 files changed, 780 deletions(-) delete mode 100644 core/src/main/java/org/acegisecurity/MethodDefinitionAttributes.java delete mode 100644 core/src/main/java/org/acegisecurity/MethodDefinitionMap.java delete mode 100644 core/src/main/java/org/acegisecurity/MethodDefinitionSource.java delete mode 100644 core/src/main/java/org/acegisecurity/MethodDefinitionSourceEditor.java delete mode 100644 core/src/main/java/org/acegisecurity/SecurityInterceptor.java diff --git a/core/src/main/java/org/acegisecurity/MethodDefinitionAttributes.java b/core/src/main/java/org/acegisecurity/MethodDefinitionAttributes.java deleted file mode 100644 index a88caebb41..0000000000 --- a/core/src/main/java/org/acegisecurity/MethodDefinitionAttributes.java +++ /dev/null @@ -1,158 +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.springframework.metadata.Attributes; - -import java.lang.reflect.Method; - -import java.util.Collection; -import java.util.Iterator; - - -/** - * Stores a {@link ConfigAttributeDefinition} for each method signature defined - * by Commons Attributes. - * - *

- * 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 appropriate ConfigAttributeDefinition 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 ConfigAttributeDefinitions defined - * by the implementing class. - * - * @return an iterator over all the ConfigAttributeDefinitions - * 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. - *

- * - * @author Ben Alex - * @version $Id$ - */ -public class SecurityInterceptor implements MethodInterceptor, InitializingBean { - //~ Static fields/initializers ============================================= - - private static final Log logger = LogFactory.getLog(SecurityInterceptor.class); - - //~ Instance fields ======================================================== - - private AccessDecisionManager accessDecisionManager; - private AuthenticationManager authenticationManager; - private MethodDefinitionSource methodDefinitionSource; - private RunAsManager runAsManager; - private boolean validateConfigAttributes = true; - - //~ Methods ================================================================ - - public void setAccessDecisionManager( - AccessDecisionManager accessDecisionManager) { - this.accessDecisionManager = accessDecisionManager; - } - - public AccessDecisionManager getAccessDecisionManager() { - return accessDecisionManager; - } - - public void setAuthenticationManager(AuthenticationManager newManager) { - this.authenticationManager = newManager; - } - - public AuthenticationManager getAuthenticationManager() { - return this.authenticationManager; - } - - public void setMethodDefinitionSource(MethodDefinitionSource newSource) { - this.methodDefinitionSource = newSource; - } - - public MethodDefinitionSource getMethodDefinitionSource() { - return this.methodDefinitionSource; - } - - public void setRunAsManager(RunAsManager runAsManager) { - this.runAsManager = runAsManager; - } - - public RunAsManager getRunAsManager() { - return runAsManager; - } - - public void setValidateConfigAttributes(boolean validateConfigAttributes) { - this.validateConfigAttributes = validateConfigAttributes; - } - - public boolean isValidateConfigAttributes() { - return validateConfigAttributes; - } - - public void afterPropertiesSet() { - if (this.authenticationManager == null) { - throw new IllegalArgumentException( - "An AuthenticationManager is required"); - } - - if (this.accessDecisionManager == null) { - throw new IllegalArgumentException( - "An AccessDecisionManager is required"); - } - - if (this.runAsManager == null) { - throw new IllegalArgumentException("A RunAsManager is required"); - } - - if (this.methodDefinitionSource == null) { - throw new IllegalArgumentException( - "A MethodDefinitionSource is required"); - } - - if (this.validateConfigAttributes) { - Iterator iter = this.methodDefinitionSource - .getConfigAttributeDefinitions(); - - if (iter == null) { - if (logger.isWarnEnabled()) { - logger.warn( - "Could not validate configuration attributes as the MethodDefinitionSource did not return a ConfigAttributeDefinition Iterator"); - } - - return; - } - - Set set = new HashSet(); - - while (iter.hasNext()) { - ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter - .next(); - Iterator attributes = def.getConfigAttributes(); - - while (attributes.hasNext()) { - ConfigAttribute attr = (ConfigAttribute) attributes.next(); - - if (!this.runAsManager.supports(attr) - && !this.accessDecisionManager.supports(attr)) { - set.add(attr); - } - } - } - - if (set.size() == 0) { - if (logger.isInfoEnabled()) { - logger.info("Validated configuration attributes"); - } - } else { - throw new IllegalArgumentException( - "Unsupported configuration attributes: " + set.toString()); - } - } - } - - /** - * Does the work of authenticating and authorizing the request. Throws - * {@link AcegiSecurityException} and its subclasses. - * - * @param mi The method being invoked which requires a security decision - * - * @return The returned value from the method invocation - * - * @throws Throwable if any error occurs - * @throws AuthenticationCredentialsNotFoundException if the - * 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; - } - } -}