View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.spring.security.interceptor;
20  
21  import org.apache.shiro.authz.annotation.*;
22  import org.apache.shiro.mgt.SecurityManager;
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
26  import org.springframework.core.annotation.AnnotationUtils;
27  
28  import java.lang.annotation.Annotation;
29  import java.lang.reflect.Method;
30  
31  
32  /**
33   * TODO - complete JavaDoc
34   *
35   * @since 0.1
36   */
37  @SuppressWarnings({"unchecked"})
38  public class AuthorizationAttributeSourceAdvisor extends StaticMethodMatcherPointcutAdvisor {
39  
40      private static final Logger log = LoggerFactory.getLogger(AuthorizationAttributeSourceAdvisor.class);
41  
42      private static final Class<? extends Annotation>[] AUTHZ_ANNOTATION_CLASSES =
43              new Class[] {
44                      RequiresPermissions.class, RequiresRoles.class,
45                      RequiresUser.class, RequiresGuest.class, RequiresAuthentication.class
46              };
47  
48      protected SecurityManager securityManager = null;
49  
50      /**
51       * Create a new AuthorizationAttributeSourceAdvisor.
52       */
53      public AuthorizationAttributeSourceAdvisor() {
54          setAdvice(new AopAllianceAnnotationsAuthorizingMethodInterceptor());
55      }
56  
57      public SecurityManager getSecurityManager() {
58          return securityManager;
59      }
60  
61      public void setSecurityManager(org.apache.shiro.mgt.SecurityManager securityManager) {
62          this.securityManager = securityManager;
63      }
64  
65      /**
66       * Returns <tt>true</tt> if the method has any Shiro annotations, false otherwise.
67       * The annotations inspected are:
68       * <ul>
69       * <li>{@link org.apache.shiro.authz.annotation.RequiresAuthentication RequiresAuthentication}</li>
70       * <li>{@link org.apache.shiro.authz.annotation.RequiresUser RequiresUser}</li>
71       * <li>{@link org.apache.shiro.authz.annotation.RequiresGuest RequiresGuest}</li>
72       * <li>{@link org.apache.shiro.authz.annotation.RequiresRoles RequiresRoles}</li>
73       * <li>{@link org.apache.shiro.authz.annotation.RequiresPermissions RequiresPermissions}</li>
74       * </ul>
75       *
76       * @param method      the method to check for a Shiro annotation
77       * @param targetClass the class potentially declaring Shiro annotations
78       * @return <tt>true</tt> if the method has a Shiro annotation, false otherwise.
79       * @see org.springframework.aop.MethodMatcher#matches(java.lang.reflect.Method, Class)
80       */
81      public boolean matches(Method method, Class targetClass) {
82          Method m = method;
83  
84          if ( isAuthzAnnotationPresent(m) ) {
85              return true;
86          }
87  
88          //The 'method' parameter could be from an interface that doesn't have the annotation.
89          //Check to see if the implementation has it.
90          if ( targetClass != null) {
91              try {
92                  m = targetClass.getMethod(m.getName(), m.getParameterTypes());
93                  if ( isAuthzAnnotationPresent(m) ) {
94                      return true;
95                  }
96              } catch (NoSuchMethodException ignored) {
97                  //default return value is false.  If we can't find the method, then obviously
98                  //there is no annotation, so just use the default return value.
99              }
100         }
101 
102         return false;
103     }
104 
105     private boolean isAuthzAnnotationPresent(Method method) {
106         for( Class<? extends Annotation> annClass : AUTHZ_ANNOTATION_CLASSES ) {
107             Annotation a = AnnotationUtils.findAnnotation(method, annClass);
108             if ( a != null ) {
109                 return true;
110             }
111         }
112         return false;
113     }
114 
115 }