SEC-99/428/429/563: Various refactoring of method security metadata support.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.security.DenyAll;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.security.ConfigAttributeDefinition;
|
||||
import org.springframework.security.intercept.method.AbstractFallbackMethodDefinitionSource;
|
||||
|
||||
|
||||
/**
|
||||
* Sources method security metadata from major JSR 250 security annotations.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Jsr250MethodDefinitionSource extends AbstractFallbackMethodDefinitionSource {
|
||||
|
||||
protected ConfigAttributeDefinition findAttributes(Class clazz) {
|
||||
return processAnnotations(clazz.getAnnotations());
|
||||
}
|
||||
|
||||
protected ConfigAttributeDefinition findAttributes(Method method, Class targetClass) {
|
||||
return processAnnotations(AnnotationUtils.getAnnotations(method));
|
||||
}
|
||||
|
||||
public Collection getConfigAttributeDefinitions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private ConfigAttributeDefinition processAnnotations(Annotation[] annotations) {
|
||||
if (annotations == null || annotations.length == 0) {
|
||||
return null;
|
||||
}
|
||||
for (Annotation a: annotations) {
|
||||
if (a instanceof DenyAll) {
|
||||
return new ConfigAttributeDefinition(Jsr250SecurityConfig.DENY_ALL_ATTRIBUTE);
|
||||
}
|
||||
if (a instanceof PermitAll) {
|
||||
return new ConfigAttributeDefinition(Jsr250SecurityConfig.PERMIT_ALL_ATTRIBUTE);
|
||||
}
|
||||
if (a instanceof RolesAllowed) {
|
||||
RolesAllowed ra = (RolesAllowed) a;
|
||||
List attributes = new ArrayList();
|
||||
for (String allowed : ra.value()) {
|
||||
attributes.add(new Jsr250SecurityConfig(allowed));
|
||||
}
|
||||
return new ConfigAttributeDefinition(attributes);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package org.springframework.security.annotation;
|
||||
|
||||
import org.springframework.security.SecurityConfig;
|
||||
import org.springframework.metadata.Attributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.annotation.security.DenyAll;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* Java 5 Annotation {@link Attributes} metadata implementation used for secure method interception using
|
||||
* the security anotations defined in JSR-250.
|
||||
* <p>
|
||||
* This <code>Attributes</code> implementation will return security configuration for classes described using the
|
||||
* Java JEE 5 annotations (<em>DenyAll</em>, <em>PermitAll</em> and <em>RolesAllowed</em>).
|
||||
* <p>
|
||||
*
|
||||
* @author Mark St.Godard
|
||||
* @author Usama Rashwan
|
||||
* @author Luke Taylor
|
||||
* @since 2.0
|
||||
*
|
||||
* @see javax.annotation.security.RolesAllowed
|
||||
*/
|
||||
|
||||
public class Jsr250SecurityAnnotationAttributes implements Attributes {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Get the <code>RolesAllowed</code> attributes for a given target class.
|
||||
* This method will return an empty Collection because the call to getAttributes(method) will override the class
|
||||
* annotation.
|
||||
*
|
||||
* @param target The target Object
|
||||
* @return Empty Collection of <code>SecurityConfig</code>
|
||||
*
|
||||
* @see Attributes#getAttributes
|
||||
*/
|
||||
public Collection<SecurityConfig> getAttributes(Class target) {
|
||||
return new HashSet<SecurityConfig>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attributes for a given target method, acording to JSR-250 precedence rules.
|
||||
*
|
||||
* @param method The target method
|
||||
* @return Collection of <code>SecurityConfig</code>
|
||||
* @see Attributes#getAttributes
|
||||
*/
|
||||
public Collection<SecurityConfig> getAttributes(Method method) {
|
||||
ArrayList<SecurityConfig> attributes = new ArrayList<SecurityConfig>();
|
||||
|
||||
if (AnnotationUtils.getAnnotation(method, DenyAll.class) != null) {
|
||||
attributes.add(Jsr250SecurityConfig.DENY_ALL_ATTRIBUTE);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
if (AnnotationUtils.getAnnotation(method, PermitAll.class) != null) {
|
||||
attributes.add(Jsr250SecurityConfig.PERMIT_ALL_ATTRIBUTE);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
RolesAllowed rolesAllowed = AnnotationUtils.getAnnotation(method, RolesAllowed.class);
|
||||
|
||||
if (rolesAllowed != null) {
|
||||
for (String role : rolesAllowed.value()) {
|
||||
attributes.add(new Jsr250SecurityConfig(role));
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// Now check the class-level attributes:
|
||||
if (method.getDeclaringClass().getAnnotation(DenyAll.class) != null) {
|
||||
attributes.add(Jsr250SecurityConfig.DENY_ALL_ATTRIBUTE);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
if (method.getDeclaringClass().getAnnotation(PermitAll.class) != null) {
|
||||
attributes.add(Jsr250SecurityConfig.PERMIT_ALL_ATTRIBUTE);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
rolesAllowed = method.getDeclaringClass().getAnnotation(RolesAllowed.class);
|
||||
|
||||
if (rolesAllowed != null) {
|
||||
for (String role : rolesAllowed.value()) {
|
||||
attributes.add(new Jsr250SecurityConfig(role));
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
protected Collection<SecurityConfig> populateSecurityConfigWithRolesAllowed (Annotation[] annotations) {
|
||||
Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
|
||||
for (Annotation annotation : annotations) {
|
||||
// check for RolesAllowed annotations
|
||||
if (annotation instanceof RolesAllowed) {
|
||||
RolesAllowed attr = (RolesAllowed) annotation;
|
||||
|
||||
for (String auth : attr.value()) {
|
||||
attributes.add(new SecurityConfig(auth));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public Collection getAttributes(Class clazz, Class filter) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Collection getAttributes(Method method, Class clazz) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Collection getAttributes(Field field) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Collection getAttributes(Field field, Class clazz) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.security.ConfigAttributeDefinition;
|
||||
import org.springframework.security.intercept.method.AbstractFallbackMethodDefinitionSource;
|
||||
|
||||
|
||||
/**
|
||||
* Sources method security metadata from Spring Security's {@link Secured} annotation.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SecuredMethodDefinitionSource extends AbstractFallbackMethodDefinitionSource {
|
||||
|
||||
protected ConfigAttributeDefinition findAttributes(Class clazz) {
|
||||
return processAnnotation(clazz.getAnnotation(Secured.class));
|
||||
}
|
||||
|
||||
protected ConfigAttributeDefinition findAttributes(Method method, Class targetClass) {
|
||||
return processAnnotation(AnnotationUtils.findAnnotation(method, Secured.class));
|
||||
}
|
||||
|
||||
public Collection getConfigAttributeDefinitions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private ConfigAttributeDefinition processAnnotation(Annotation a) {
|
||||
if (a == null || !(a instanceof Secured)) {
|
||||
return null;
|
||||
}
|
||||
Secured secured = (Secured) a;
|
||||
return new ConfigAttributeDefinition(secured.value());
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 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 org.springframework.security.annotation;
|
||||
|
||||
import org.springframework.security.SecurityConfig;
|
||||
|
||||
import org.springframework.metadata.Attributes;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Java 5 Annotation <code>Attributes</code> metadata implementation used for secure method interception.<p>This
|
||||
* <code>Attributes</code> implementation will return security configuration for classes described using the
|
||||
* <code>Secured</code> Java 5 annotation.
|
||||
* <p>
|
||||
* The <code>SecurityAnnotationAttributes</code> implementation can be used to configure a
|
||||
* <code>MethodDefinitionAttributes</code> and <code>MethodSecurityInterceptor</code> bean definition (see below).
|
||||
* <p>
|
||||
* For example:
|
||||
* <pre>
|
||||
* <bean id="attributes" class="org.springframework.security.annotation.SecurityAnnotationAttributes"/>
|
||||
* <bean id="objectDefinitionSource"
|
||||
* class="org.springframework.security.intercept.method.MethodDefinitionAttributes">
|
||||
* <property name="attributes"><ref local="attributes"/></property>
|
||||
* </bean>
|
||||
* <bean id="securityInterceptor"
|
||||
* class="org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
* . . .
|
||||
* <property name="objectDefinitionSource"><ref local="objectDefinitionSource"/></property>
|
||||
* </bean>
|
||||
* </pre>
|
||||
* <p>
|
||||
* These security annotations are similiar to the Commons Attributes approach, however they are using Java 5
|
||||
* language-level metadata support.
|
||||
*
|
||||
* @author Mark St.Godard
|
||||
* @version $Id$
|
||||
*
|
||||
* @see org.springframework.security.annotation.Secured
|
||||
*/
|
||||
public class SecurityAnnotationAttributes implements Attributes {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Get the <code>Secured</code> attributes for a given target class.
|
||||
*
|
||||
* @param target The target method
|
||||
*
|
||||
* @return Collection of <code>SecurityConfig</code>
|
||||
*
|
||||
* @see Attributes#getAttributes
|
||||
*/
|
||||
public Collection getAttributes(Class target) {
|
||||
Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
|
||||
|
||||
for (Annotation annotation : target.getAnnotations()) {
|
||||
// check for Secured annotations
|
||||
if (annotation instanceof Secured) {
|
||||
Secured attr = (Secured) annotation;
|
||||
|
||||
for (String auth : attr.value()) {
|
||||
attributes.add(new SecurityConfig(auth));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <code>Secured</code> attributes for a given target method.
|
||||
*
|
||||
* @param method The target method
|
||||
*
|
||||
* @return Collection of <code>SecurityConfig</code>
|
||||
*
|
||||
* @see Attributes#getAttributes
|
||||
*/
|
||||
public Collection getAttributes(Method method) {
|
||||
Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
|
||||
Annotation[] annotations = AnnotationUtils.getAnnotations(method);
|
||||
|
||||
for (Annotation annotation : annotations) {
|
||||
// check for Secured annotations
|
||||
if (annotation instanceof Secured) {
|
||||
Secured attr = (Secured) annotation;
|
||||
|
||||
for (String auth : attr.value()) {
|
||||
attributes.add(new SecurityConfig(auth));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public Collection getAttributes(Class clazz, Class filter) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Collection getAttributes(Method method, Class clazz) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Collection getAttributes(Field field) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Collection getAttributes(Field field, Class clazz) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package org.springframework.security.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.annotation.security.DenyAll;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.ConfigAttributeDefinition;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Jsr250MethodDefinitionSourceTests {
|
||||
Jsr250MethodDefinitionSource mds = new Jsr250MethodDefinitionSource();
|
||||
A a = new A();
|
||||
UserAllowedClass userAllowed = new UserAllowedClass();
|
||||
DenyAllClass denyAll = new DenyAllClass();
|
||||
|
||||
@Test
|
||||
public void methodWithRolesAllowedHasCorrectAttribute() throws Exception {
|
||||
ConfigAttributeDefinition accessAttributes = mds.findAttributes(a.getClass().getMethod("adminMethod"), null);
|
||||
assertEquals(1, accessAttributes.getConfigAttributes().size());
|
||||
assertEquals("ADMIN", accessAttributes.getConfigAttributes().iterator().next().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void permitAllMethodHasPermitAllAttribute() throws Exception {
|
||||
ConfigAttributeDefinition accessAttributes = mds.findAttributes(a.getClass().getMethod("permitAllMethod"), null);
|
||||
assertEquals(1, accessAttributes.getConfigAttributes().size());
|
||||
assertEquals("javax.annotation.security.PermitAll", accessAttributes.getConfigAttributes().iterator().next().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRoleMethodHasDenyAllAttributeWithDenyAllClass() throws Exception {
|
||||
ConfigAttributeDefinition accessAttributes = mds.findAttributes(denyAll.getClass());
|
||||
assertEquals(1, accessAttributes.getConfigAttributes().size());
|
||||
assertEquals("javax.annotation.security.DenyAll", accessAttributes.getConfigAttributes().iterator().next().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void adminMethodHasAdminAttributeWithDenyAllClass() throws Exception {
|
||||
ConfigAttributeDefinition accessAttributes = mds.findAttributes(denyAll.getClass().getMethod("adminMethod"), null);
|
||||
assertEquals(1, accessAttributes.getConfigAttributes().size());
|
||||
assertEquals("ADMIN", accessAttributes.getConfigAttributes().iterator().next().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRoleMethodHasNoAttributes() throws Exception {
|
||||
ConfigAttributeDefinition accessAttributes = mds.findAttributes(a.getClass().getMethod("noRoleMethod"), null);
|
||||
Assert.assertNull(accessAttributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classRoleIsAppliedToNoRoleMethod() throws Exception {
|
||||
ConfigAttributeDefinition accessAttributes = mds.findAttributes(userAllowed.getClass().getMethod("noRoleMethod"), null);
|
||||
Assert.assertNull(accessAttributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodRoleOverridesClassRole() throws Exception {
|
||||
ConfigAttributeDefinition accessAttributes = mds.findAttributes(userAllowed.getClass().getMethod("adminMethod"), null);
|
||||
assertEquals(1, accessAttributes.getConfigAttributes().size());
|
||||
assertEquals("ADMIN", accessAttributes.getConfigAttributes().iterator().next().toString());
|
||||
}
|
||||
|
||||
//~ Inner Classes ======================================================================================================
|
||||
|
||||
public static class A {
|
||||
|
||||
public void noRoleMethod() {}
|
||||
|
||||
@RolesAllowed("ADMIN")
|
||||
public void adminMethod() {}
|
||||
|
||||
@PermitAll
|
||||
public void permitAllMethod() {}
|
||||
}
|
||||
|
||||
@RolesAllowed("USER")
|
||||
public static class UserAllowedClass {
|
||||
public void noRoleMethod() {}
|
||||
|
||||
@RolesAllowed("ADMIN")
|
||||
public void adminMethod() {}
|
||||
}
|
||||
|
||||
@DenyAll
|
||||
public static class DenyAllClass {
|
||||
|
||||
public void noRoleMethod() {}
|
||||
|
||||
@RolesAllowed("ADMIN")
|
||||
public void adminMethod() {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package org.springframework.security.annotation;
|
||||
|
||||
import org.springframework.security.SecurityConfig;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.annotation.security.DenyAll;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Jsr250SecurityAnnotationAttributesTests {
|
||||
Jsr250SecurityAnnotationAttributes attributes = new Jsr250SecurityAnnotationAttributes();
|
||||
A a = new A();
|
||||
UserAllowedClass userAllowed = new UserAllowedClass();
|
||||
DenyAllClass denyAll = new DenyAllClass();
|
||||
|
||||
@Test
|
||||
public void methodWithRolesAllowedHasCorrectAttribute() throws Exception {
|
||||
// Method[] methods = a.getClass().getMethods();
|
||||
|
||||
List<SecurityConfig> accessAttributes =
|
||||
new ArrayList<SecurityConfig>(attributes.getAttributes(a.getClass().getMethod("adminMethod")));
|
||||
assertEquals(1, accessAttributes.size());
|
||||
assertEquals("ADMIN", accessAttributes.get(0).getAttribute());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void permitAllMethodHasPermitAllAttribute() throws Exception {
|
||||
List<SecurityConfig> accessAttributes =
|
||||
new ArrayList<SecurityConfig>(attributes.getAttributes(a.getClass().getMethod("permitAllMethod")));
|
||||
assertEquals(1, accessAttributes.size());
|
||||
assertEquals("javax.annotation.security.PermitAll", accessAttributes.get(0).getAttribute());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRoleMethodHasDenyAllAttributeWithDenyAllClass() throws Exception {
|
||||
List<SecurityConfig> accessAttributes =
|
||||
new ArrayList<SecurityConfig>(attributes.getAttributes(denyAll.getClass().getMethod("noRoleMethod")));
|
||||
assertEquals(1, accessAttributes.size());
|
||||
assertEquals("javax.annotation.security.DenyAll", accessAttributes.get(0).getAttribute());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void adminMethodHasAdminAttributeWithDenyAllClass() throws Exception {
|
||||
List<SecurityConfig> accessAttributes =
|
||||
new ArrayList<SecurityConfig>(attributes.getAttributes(denyAll.getClass().getMethod("adminMethod")));
|
||||
assertEquals(1, accessAttributes.size());
|
||||
assertEquals("ADMIN", accessAttributes.get(0).getAttribute());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noRoleMethodHasNoAttributes() throws Exception {
|
||||
List<SecurityConfig> accessAttributes =
|
||||
new ArrayList<SecurityConfig>(attributes.getAttributes(a.getClass().getMethod("noRoleMethod")));
|
||||
assertEquals(0, accessAttributes.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classRoleIsAppliedToNoRoleMethod() throws Exception {
|
||||
List<SecurityConfig> accessAttributes =
|
||||
new ArrayList<SecurityConfig>(attributes.getAttributes(userAllowed.getClass().getMethod("noRoleMethod")));
|
||||
assertEquals(1, accessAttributes.size());
|
||||
assertEquals("USER", accessAttributes.get(0).getAttribute());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodRoleOverridesClassRole() throws Exception {
|
||||
List<SecurityConfig> accessAttributes =
|
||||
new ArrayList<SecurityConfig>(attributes.getAttributes(userAllowed.getClass().getMethod("adminMethod")));
|
||||
assertEquals(1, accessAttributes.size());
|
||||
assertEquals("ADMIN", accessAttributes.get(0).getAttribute());
|
||||
}
|
||||
|
||||
//~ Inner Classes ======================================================================================================
|
||||
|
||||
public static class A {
|
||||
|
||||
public void noRoleMethod() {}
|
||||
|
||||
@RolesAllowed("ADMIN")
|
||||
public void adminMethod() {}
|
||||
|
||||
@PermitAll
|
||||
public void permitAllMethod() {}
|
||||
}
|
||||
|
||||
@RolesAllowed("USER")
|
||||
public static class UserAllowedClass {
|
||||
public void noRoleMethod() {}
|
||||
|
||||
@RolesAllowed("ADMIN")
|
||||
public void adminMethod() {}
|
||||
}
|
||||
|
||||
@DenyAll
|
||||
public static class DenyAllClass {
|
||||
|
||||
public void noRoleMethod() {}
|
||||
|
||||
@RolesAllowed("ADMIN")
|
||||
public void adminMethod() {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -20,20 +20,17 @@ import java.lang.reflect.Method;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.security.ConfigAttributeDefinition;
|
||||
import org.springframework.security.annotation.test.Entity;
|
||||
import org.springframework.security.annotation.test.OrganisationService;
|
||||
import org.springframework.security.annotation.test.PersonService;
|
||||
import org.springframework.security.annotation.test.PersonServiceImpl;
|
||||
import org.springframework.security.annotation.test.Service;
|
||||
import org.springframework.security.annotation.test.ServiceImpl;
|
||||
import org.springframework.security.intercept.method.MethodDefinitionMap;
|
||||
import org.springframework.security.intercept.method.MapBasedMethodDefinitionSource;
|
||||
import org.springframework.security.intercept.method.MethodDefinitionSourceEditor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
|
||||
/**
|
||||
* Extra tests to demonstrate generics behaviour with <code>MethodDefinitionMap</code>.
|
||||
* Extra tests to demonstrate generics behaviour with <code>MapBasedMethodDefinitionSource</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
@@ -41,58 +38,53 @@ import org.aopalliance.intercept.MethodInvocation;
|
||||
public class MethodDefinitionSourceEditorTigerTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void testConcreteClassInvocationsAlsoReturnDefinitionsAgainstInterface() throws Exception {
|
||||
public void testConcreteClassInvocations() throws Exception {
|
||||
MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
|
||||
editor.setAsText(
|
||||
"org.springframework.security.annotation.test.Service.makeLower*=ROLE_FROM_INTERFACE\r\norg.springframework.security.annotation.test.Service.makeUpper*=ROLE_FROM_INTERFACE\r\norg.springframework.security.annotation.test.ServiceImpl.makeUpper*=ROLE_FROM_IMPLEMENTATION");
|
||||
"org.springframework.security.annotation.test.Service.makeLower*=ROLE_FROM_INTERFACE\r\n" +
|
||||
"org.springframework.security.annotation.test.Service.makeUpper*=ROLE_FROM_INTERFACE\r\n" +
|
||||
"org.springframework.security.annotation.test.ServiceImpl.makeUpper*=ROLE_FROM_IMPLEMENTATION");
|
||||
|
||||
MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
|
||||
MapBasedMethodDefinitionSource map = (MapBasedMethodDefinitionSource) editor.getValue();
|
||||
assertEquals(3, map.getMethodMapSize());
|
||||
|
||||
ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(Service.class,
|
||||
"makeLowerCase", new Class[]{Entity.class}));
|
||||
"makeLowerCase", new Class[]{Entity.class}, new PersonServiceImpl()));
|
||||
ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition("ROLE_FROM_INTERFACE");
|
||||
assertEquals(expectedMakeLower, returnedMakeLower);
|
||||
|
||||
ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(ServiceImpl.class,
|
||||
"makeUpperCase", new Class[]{Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(new String[]{"ROLE_FROM_IMPLEMENTATION", "ROLE_FROM_INTERFACE"});
|
||||
ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(Service.class,
|
||||
"makeUpperCase", new Class[]{Entity.class}, new PersonServiceImpl()));
|
||||
ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(new String[]{"ROLE_FROM_IMPLEMENTATION"});
|
||||
assertEquals(expectedMakeUpper, returnedMakeUpper);
|
||||
}
|
||||
|
||||
public void testGenericsSuperclassDeclarationsAreIncludedWhenSubclassesOverride() throws Exception {
|
||||
public void testBridgeMethodResolution() throws Exception {
|
||||
MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
|
||||
editor.setAsText(
|
||||
"org.springframework.security.annotation.test.Service.makeLower*=ROLE_FROM_INTERFACE\r\norg.springframework.security.annotation.test.Service.makeUpper*=ROLE_FROM_INTERFACE\r\norg.springframework.security.annotation.test.ServiceImpl.makeUpper*=ROLE_FROM_IMPLEMENTATION");
|
||||
"org.springframework.security.annotation.test.PersonService.makeUpper*=ROLE_FROM_INTERFACE\r\n" +
|
||||
"org.springframework.security.annotation.test.ServiceImpl.makeUpper*=ROLE_FROM_ABSTRACT\r\n" +
|
||||
"org.springframework.security.annotation.test.PersonServiceImpl.makeUpper*=ROLE_FROM_PSI");
|
||||
|
||||
MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
|
||||
MapBasedMethodDefinitionSource map = (MapBasedMethodDefinitionSource) editor.getValue();
|
||||
assertEquals(3, map.getMethodMapSize());
|
||||
|
||||
ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(PersonService.class,
|
||||
"makeLowerCase", new Class[]{Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition("ROLE_FROM_INTERFACE");
|
||||
assertEquals(expectedMakeLower, returnedMakeLower);
|
||||
|
||||
ConfigAttributeDefinition returnedMakeLower2 = map.getAttributes(new MockMethodInvocation(
|
||||
OrganisationService.class, "makeLowerCase", new Class[]{Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeLower2 = new ConfigAttributeDefinition("ROLE_FROM_INTERFACE");
|
||||
assertEquals(expectedMakeLower2, returnedMakeLower2);
|
||||
|
||||
ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(
|
||||
PersonServiceImpl.class, "makeUpperCase", new Class[]{Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(new String[]{"ROLE_FROM_IMPLEMENTATION", "ROLE_FROM_INTERFACE"});
|
||||
ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(Service.class,
|
||||
"makeUpperCase", new Class[]{Entity.class}, new PersonServiceImpl()));
|
||||
ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(new String[]{"ROLE_FROM_PSI"});
|
||||
assertEquals(expectedMakeUpper, returnedMakeUpper);
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockMethodInvocation implements MethodInvocation {
|
||||
Method method;
|
||||
private Method method;
|
||||
private Object targetObject;
|
||||
|
||||
public MockMethodInvocation(Class clazz, String methodName, Class[] parameterTypes)
|
||||
public MockMethodInvocation(Class clazz, String methodName, Class[] parameterTypes, Object targetObject)
|
||||
throws NoSuchMethodException {
|
||||
System.out.println(clazz + " " + methodName + " " + parameterTypes[0]);
|
||||
method = clazz.getMethod(methodName, parameterTypes);
|
||||
this.method = clazz.getMethod(methodName, parameterTypes);
|
||||
this.targetObject = targetObject;
|
||||
}
|
||||
|
||||
public Object[] getArguments() {
|
||||
@@ -108,11 +100,12 @@ public class MethodDefinitionSourceEditorTigerTests extends TestCase {
|
||||
}
|
||||
|
||||
public Object getThis() {
|
||||
return null;
|
||||
return targetObject;
|
||||
}
|
||||
|
||||
public Object proceed() throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,41 +14,33 @@
|
||||
*/
|
||||
package org.springframework.security.annotation;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.security.SecurityConfig;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.metadata.Attributes;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.Collection;
|
||||
import org.springframework.security.ConfigAttributeDefinition;
|
||||
import org.springframework.security.SecurityConfig;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for {@link org.springframework.security.annotation.SecurityAnnotationAttributes}
|
||||
* Tests for {@link org.springframework.security.annotation.SecuredMethodDefinitionSource}
|
||||
*
|
||||
* @author Mark St.Godard
|
||||
* @author Joe Scalise
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SecurityAnnotationAttributesTests extends TestCase {
|
||||
public class SecuredMethodDefinitionSourceTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Attributes attributes;
|
||||
private Log logger = LogFactory.getLog(SecurityAnnotationAttributesTests.class);
|
||||
private SecuredMethodDefinitionSource mds = new SecuredMethodDefinitionSource();;
|
||||
private Log logger = LogFactory.getLog(SecuredMethodDefinitionSourceTests.class);
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
// create the Annotations impl
|
||||
this.attributes = new SecurityAnnotationAttributes();
|
||||
}
|
||||
|
||||
public void testGenericsSuperclassDeclarationsAreIncludedWhenSubclassesOverride() {
|
||||
Method method = null;
|
||||
|
||||
@@ -58,20 +50,19 @@ public class SecurityAnnotationAttributesTests extends TestCase {
|
||||
fail("Should be a superMethod called 'someUserMethod3' on class!");
|
||||
}
|
||||
|
||||
Collection attrs = this.attributes.getAttributes(method);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("attrs: ");
|
||||
logger.debug(attrs);
|
||||
}
|
||||
ConfigAttributeDefinition attrs = this.mds.findAttributes(method, DepartmentServiceImpl.class);
|
||||
|
||||
assertNotNull(attrs);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("attrs: " + StringUtils.collectionToCommaDelimitedString(attrs.getConfigAttributes()));
|
||||
}
|
||||
|
||||
// expect 1 attribute
|
||||
assertTrue("Did not find 1 attribute", attrs.size() == 1);
|
||||
assertTrue("Did not find 1 attribute", attrs.getConfigAttributes().size() == 1);
|
||||
|
||||
// should have 1 SecurityConfig
|
||||
for (Object obj : attrs) {
|
||||
for (Object obj : attrs.getConfigAttributes()) {
|
||||
assertTrue(obj instanceof SecurityConfig);
|
||||
|
||||
SecurityConfig sc = (SecurityConfig) obj;
|
||||
@@ -86,67 +77,39 @@ public class SecurityAnnotationAttributesTests extends TestCase {
|
||||
fail("Should be a superMethod called 'someUserMethod3' on class!");
|
||||
}
|
||||
|
||||
System.out.println(superMethod);
|
||||
|
||||
Collection superAttrs = this.attributes.getAttributes(superMethod);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("superAttrs: ");
|
||||
logger.debug(superAttrs);
|
||||
}
|
||||
ConfigAttributeDefinition superAttrs = this.mds.findAttributes(superMethod, DepartmentServiceImpl.class);
|
||||
|
||||
assertNotNull(superAttrs);
|
||||
|
||||
// TODO: Enable this part of the test once we can build against Spring 2.0+ and above only (SEC-274)
|
||||
/*
|
||||
// expect 1 attribute
|
||||
assertTrue("Did not find 1 attribute", superAttrs.size() == 1);
|
||||
// should have 1 SecurityConfig
|
||||
for (Object obj : superAttrs) {
|
||||
assertTrue(obj instanceof SecurityConfig);
|
||||
SecurityConfig sc = (SecurityConfig) obj;
|
||||
assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
|
||||
}
|
||||
*/
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("superAttrs: " + StringUtils.collectionToCommaDelimitedString(superAttrs.getConfigAttributes()));
|
||||
}
|
||||
|
||||
// This part of the test relates to SEC-274
|
||||
// expect 1 attribute
|
||||
assertTrue("Did not find 1 attribute", superAttrs.getConfigAttributes().size() == 1);
|
||||
// should have 1 SecurityConfig
|
||||
for (Object obj : superAttrs.getConfigAttributes()) {
|
||||
assertTrue(obj instanceof SecurityConfig);
|
||||
SecurityConfig sc = (SecurityConfig) obj;
|
||||
assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetAttributesClass() {
|
||||
Collection attrs = this.attributes.getAttributes(BusinessService.class);
|
||||
ConfigAttributeDefinition attrs = this.mds.findAttributes(BusinessService.class);
|
||||
|
||||
assertNotNull(attrs);
|
||||
|
||||
// expect 1 annotation
|
||||
assertTrue(attrs.size() == 1);
|
||||
assertTrue(attrs.getConfigAttributes().size() == 1);
|
||||
|
||||
// should have 1 SecurityConfig
|
||||
SecurityConfig sc = (SecurityConfig) attrs.iterator().next();
|
||||
SecurityConfig sc = (SecurityConfig) attrs.getConfigAttributes().iterator().next();
|
||||
|
||||
assertTrue(sc.getAttribute().equals("ROLE_USER"));
|
||||
}
|
||||
|
||||
public void testGetAttributesClassClass() {
|
||||
try {
|
||||
this.attributes.getAttributes(BusinessService.class, null);
|
||||
fail("Unsupported method should have thrown an exception!");
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
|
||||
public void testGetAttributesField() {
|
||||
try {
|
||||
Field field = null;
|
||||
this.attributes.getAttributes(field);
|
||||
fail("Unsupported method should have thrown an exception!");
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
|
||||
public void testGetAttributesFieldClass() {
|
||||
try {
|
||||
Field field = null;
|
||||
this.attributes.getAttributes(field, null);
|
||||
fail("Unsupported method should have thrown an exception!");
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
|
||||
public void testGetAttributesMethod() {
|
||||
Method method = null;
|
||||
|
||||
@@ -156,18 +119,18 @@ public class SecurityAnnotationAttributesTests extends TestCase {
|
||||
fail("Should be a method called 'someUserAndAdminMethod' on class!");
|
||||
}
|
||||
|
||||
Collection attrs = this.attributes.getAttributes(method);
|
||||
ConfigAttributeDefinition attrs = this.mds.findAttributes(method, BusinessService.class);
|
||||
|
||||
assertNotNull(attrs);
|
||||
|
||||
// expect 2 attributes
|
||||
assertTrue(attrs.size() == 2);
|
||||
assertTrue(attrs.getConfigAttributes().size() == 2);
|
||||
|
||||
boolean user = false;
|
||||
boolean admin = false;
|
||||
|
||||
// should have 2 SecurityConfigs
|
||||
for (Object obj : attrs) {
|
||||
for (Object obj : attrs.getConfigAttributes()) {
|
||||
assertTrue(obj instanceof SecurityConfig);
|
||||
|
||||
SecurityConfig sc = (SecurityConfig) obj;
|
||||
@@ -182,19 +145,5 @@ public class SecurityAnnotationAttributesTests extends TestCase {
|
||||
// expect to have ROLE_USER and ROLE_ADMIN
|
||||
assertTrue(user && admin);
|
||||
}
|
||||
|
||||
public void testGetAttributesMethodClass() {
|
||||
Method method = null;
|
||||
|
||||
try {
|
||||
method = BusinessService.class.getMethod("someUserAndAdminMethod", new Class[] {});
|
||||
} catch (NoSuchMethodException unexpected) {
|
||||
fail("Should be a method called 'someUserAndAdminMethod' on class!");
|
||||
}
|
||||
|
||||
try {
|
||||
this.attributes.getAttributes(method, null);
|
||||
fail("Unsupported method should have thrown an exception!");
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user