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.authz.aop;
20  
21  import org.apache.shiro.aop.AnnotationMethodInterceptor;
22  import org.apache.shiro.aop.AnnotationResolver;
23  import org.apache.shiro.aop.MethodInvocation;
24  import org.apache.shiro.authz.AuthorizationException;
25  
26  
27  /**
28   * An <tt>AnnotationMethodInterceptor</tt> that asserts the calling code is authorized to execute the method
29   * before allowing the invocation to continue by inspecting code annotations to perform an access control check.
30   *
31   * @since 0.1
32   */
33  public abstract class AuthorizingAnnotationMethodInterceptor extends AnnotationMethodInterceptor
34  {
35      
36      /**
37       * Constructor that ensures the internal <code>handler</code> is set which will be used to perform the
38       * authorization assertion checks when a supported annotation is encountered.
39       * @param handler the internal <code>handler</code> used to perform authorization assertion checks when a 
40       * supported annotation is encountered.
41       */
42      public AuthorizingAnnotationMethodInterceptor( AuthorizingAnnotationHandler handler ) {
43          super(handler);
44      }
45  
46      /**
47       *
48       * @param handler
49       * @param resolver
50       * @since 1.1
51       */
52      public AuthorizingAnnotationMethodInterceptor( AuthorizingAnnotationHandler handler,
53                                                     AnnotationResolver resolver) {
54          super(handler, resolver);
55      }
56  
57      /**
58       * Ensures the <code>methodInvocation</code> is allowed to execute first before proceeding by calling the
59       * {@link #assertAuthorized(org.apache.shiro.aop.MethodInvocation) assertAuthorized} method first.
60       *
61       * @param methodInvocation the method invocation to check for authorization prior to allowing it to proceed/execute.
62       * @return the return value from the method invocation (the value of {@link org.apache.shiro.aop.MethodInvocation#proceed() MethodInvocation.proceed()}).
63       * @throws org.apache.shiro.authz.AuthorizationException if the <code>MethodInvocation</code> is not allowed to proceed.
64       * @throws Throwable if any other error occurs.
65       */
66      public Object invoke(MethodInvocation methodInvocation) throws Throwable {
67          assertAuthorized(methodInvocation);
68          return methodInvocation.proceed();
69      }
70  
71      /**
72       * Ensures the calling Subject is authorized to execute the specified <code>MethodInvocation</code>.
73       * <p/>
74       * As this is an AnnotationMethodInterceptor, this implementation merely delegates to the internal
75       * {@link AuthorizingAnnotationHandler AuthorizingAnnotationHandler} by first acquiring the annotation by
76       * calling {@link #getAnnotation(MethodInvocation) getAnnotation(methodInvocation)} and then calls
77       * {@link AuthorizingAnnotationHandler#assertAuthorized(java.lang.annotation.Annotation) handler.assertAuthorized(annotation)}.
78       *
79       * @param mi the <code>MethodInvocation</code> to check to see if it is allowed to proceed/execute.
80       * @throws AuthorizationException if the method invocation is not allowed to continue/execute.
81       */
82      public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
83          try {
84              ((AuthorizingAnnotationHandler)getHandler()).assertAuthorized(getAnnotation(mi));
85          }
86          catch(AuthorizationException ae) {
87              // Annotation handler doesn't know why it was called, so add the information here if possible. 
88              // Don't wrap the exception here since we don't want to mask the specific exception, such as 
89              // UnauthenticatedException etc. 
90              if (ae.getCause() == null) ae.initCause(new AuthorizationException("Not authorized to invoke method: " + mi.getMethod()));
91              throw ae;
92          }         
93      }
94  }