SEC-1796: Check for annotated annotations at class/interface level. Previously only the specific security annotation was checked for. By delegating to Spring's AnnotationUtils, custom annotations carrying the security annotation are also detected.

This commit is contained in:
Luke Taylor
2011-08-12 14:29:55 +01:00
parent 8ce4d326f5
commit 74daa68691
7 changed files with 178 additions and 148 deletions

View File

@@ -55,7 +55,7 @@ public class SecuredAnnotationSecurityMetadataSource extends AbstractFallbackMet
}
protected Collection<ConfigAttribute> findAttributes(Class<?> clazz) {
return processAnnotation(clazz.getAnnotation(annotationType));
return processAnnotation(AnnotationUtils.findAnnotation(clazz, annotationType));
}
protected Collection<ConfigAttribute> findAttributes(Method method, Class<?> targetClass) {

View File

@@ -19,6 +19,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.*;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Pointcut;
@@ -113,7 +114,8 @@ public class MethodSecurityMetadataSourceAdvisor extends AbstractPointcutAdvisor
class MethodSecurityMetadataSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@SuppressWarnings("unchecked")
public boolean matches(Method m, Class targetClass) {
return attributeSource.getAttributes(m, targetClass) != null;
Collection attributes = attributeSource.getAttributes(m, targetClass);
return attributes != null && !attributes.isEmpty();
}
}
}

View File

@@ -1,7 +1,7 @@
package org.springframework.security.access.method;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.*;
import org.springframework.aop.support.AopUtils;
import org.springframework.security.access.ConfigAttribute;
@@ -51,7 +51,7 @@ public abstract class AbstractFallbackMethodSecurityMetadataSource extends Abstr
// Last fallback is the class of the original method.
return findAttributes(method.getDeclaringClass());
}
return null;
return Collections.emptyList();
}
/**

View File

@@ -2,8 +2,7 @@ package org.springframework.security.access.prepost;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.security.access.ConfigAttribute;
@@ -38,13 +37,12 @@ public class PrePostAnnotationSecurityMetadataSource extends AbstractMethodSecur
public Collection<ConfigAttribute> getAttributes(Method method, Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
return Collections.emptyList();
}
logger.trace("Looking for Pre/Post annotations for method '" +
method.getName() + "' on target class '" + targetClass + "'");
PreFilter preFilter = findAnnotation(method, targetClass, PreFilter.class);
PreAuthorize preAuthorize = findAnnotation(method, targetClass, PreAuthorize.class);
PostFilter postFilter = findAnnotation(method, targetClass, PostFilter.class);
// TODO: Can we check for void methods and throw an exception here?
@@ -53,7 +51,7 @@ public class PrePostAnnotationSecurityMetadataSource extends AbstractMethodSecur
if (preFilter == null && preAuthorize == null && postFilter == null && postAuthorize == null ) {
// There is no meta-data so return
logger.trace("No expression annotations found");
return null;
return Collections.emptyList();
}
String preFilterAttribute = preFilter == null ? null : preFilter.value();
@@ -78,7 +76,7 @@ public class PrePostAnnotationSecurityMetadataSource extends AbstractMethodSecur
attrs.trimToSize();
return attrs.isEmpty() ? null : attrs;
return attrs;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
@@ -112,23 +110,13 @@ public class PrePostAnnotationSecurityMetadataSource extends AbstractMethodSecur
}
// Check the class-level (note declaringClass, not targetClass, which may not actually implement the method)
annotation = specificMethod.getDeclaringClass().getAnnotation(annotationClass);
annotation = AnnotationUtils.findAnnotation(specificMethod.getDeclaringClass(), annotationClass);
if (annotation != null) {
logger.debug(annotation + " found on: " + specificMethod.getDeclaringClass().getName());
return annotation;
}
// Check for a possible interface annotation which would not be inherited by the declaring class
if (specificMethod != method) {
annotation = method.getDeclaringClass().getAnnotation(annotationClass);
if (annotation != null) {
logger.debug(annotation + " found on: " + method.getDeclaringClass().getName());
return annotation;
}
}
return null;
}