001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015: package org.acegisecurity.annotation;
016:
017: import org.acegisecurity.SecurityConfig;
018:
019: import org.springframework.metadata.Attributes;
020:
021: import org.springframework.util.ClassUtils;
022:
023: import java.lang.annotation.Annotation;
024: import java.lang.reflect.Field;
025: import java.lang.reflect.Method;
026:
027: import java.util.Collection;
028: import java.util.HashSet;
029: import java.util.Set;
030:
031: /**
032: * Java 5 Annotation <code>Attributes</code> metadata implementation used for secure method interception.<p>This
033: * <code>Attributes</code> implementation will return security configuration for classes described using the
034: * <code>Secured</code> Java 5 annotation.</p>
035: * <p>The <code>SecurityAnnotationAttributes</code> implementation can be used to configure a
036: * <code>MethodDefinitionAttributes</code> and <code>MethodSecurityInterceptor</code> bean definition (see below).</p>
037: * <p>For example:<pre><bean id="attributes"
038: * class="org.acegisecurity.annotation.SecurityAnnotationAttributes"/><bean id="objectDefinitionSource"
039: * class="org.acegisecurity.intercept.method.MethodDefinitionAttributes"> <property name="attributes">
040: * <ref local="attributes"/> </property></bean><bean id="securityInterceptor"
041: * class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"> . . .
042: * <property name="objectDefinitionSource"> <ref local="objectDefinitionSource"/> </property>
043: * </bean></pre></p>
044: * <p>These security annotations are similiar to the Commons Attributes approach, however they are using Java 5
045: * language-level metadata support.</p>
046: * <p>This class should be used with Spring 2.0 or above, as it relies upon utility classes in Spring 2.0 for
047: * correct introspection of annotations on bridge methods.</p>
048: *
049: * @author Mark St.Godard
050: * @version $Id: SecurityAnnotationAttributes.java 1756 2006-11-17 02:17:45Z benalex $
051: *
052: * @see org.acegisecurity.annotation.Secured
053: */
054: public class SecurityAnnotationAttributes implements Attributes {
055: //~ Methods ========================================================================================================
056:
057: /**
058: * Get the <code>Secured</code> attributes for a given target class.
059: *
060: * @param target The target method
061: *
062: * @return Collection of <code>SecurityConfig</code>
063: *
064: * @see Attributes#getAttributes
065: */
066: public Collection getAttributes(Class target) {
067: Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
068:
069: for (Annotation annotation : target.getAnnotations()) {
070: // check for Secured annotations
071: if (annotation instanceof Secured) {
072: Secured attr = (Secured) annotation;
073:
074: for (String auth : attr.value()) {
075: attributes.add(new SecurityConfig(auth));
076: }
077:
078: break;
079: }
080: }
081:
082: return attributes;
083: }
084:
085: public Collection getAttributes(Class clazz, Class filter) {
086: throw new UnsupportedOperationException("Unsupported operation");
087: }
088:
089: /**
090: * Get the <code>Secured</code> attributes for a given target method.
091: *
092: * @param method The target method
093: *
094: * @return Collection of <code>SecurityConfig</code>
095: *
096: * @see Attributes#getAttributes
097: */
098: public Collection getAttributes(Method method) {
099: Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
100:
101: Annotation[] annotations = null;
102:
103: // Use AnnotationUtils if in classpath (ie Spring 1.2.9+ deployment)
104: try {
105: Class clazz = ClassUtils
106: .forName("org.springframework.core.annotation.AnnotationUtils");
107: Method m = clazz.getMethod("getAnnotations",
108: new Class[] { Method.class });
109: annotations = (Annotation[]) m.invoke(null,
110: new Object[] { method });
111: } catch (Exception ex) {
112: // Fallback to manual retrieval if no AnnotationUtils available
113: annotations = method.getAnnotations();
114: }
115:
116: for (Annotation annotation : annotations) {
117: // check for Secured annotations
118: if (annotation instanceof Secured) {
119: Secured attr = (Secured) annotation;
120:
121: for (String auth : attr.value()) {
122: attributes.add(new SecurityConfig(auth));
123: }
124:
125: break;
126: }
127: }
128:
129: return attributes;
130: }
131:
132: public Collection getAttributes(Method method, Class clazz) {
133: throw new UnsupportedOperationException("Unsupported operation");
134: }
135:
136: public Collection getAttributes(Field field) {
137: throw new UnsupportedOperationException("Unsupported operation");
138: }
139:
140: public Collection getAttributes(Field field, Class clazz) {
141: throw new UnsupportedOperationException("Unsupported operation");
142: }
143: }
|