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.aopalliance.intercept.MethodInterceptor; 22 import org.aopalliance.intercept.MethodInvocation; 23 import org.apache.shiro.aop.AnnotationResolver; 24 import org.apache.shiro.authz.aop.*; 25 import org.apache.shiro.spring.aop.SpringAnnotationResolver; 26 27 import java.lang.reflect.Method; 28 import java.util.ArrayList; 29 import java.util.List; 30 31 /** 32 * Allows Shiro Annotations to work in any <a href="http://aopalliance.sourceforge.net/">AOP Alliance</a> 33 * specific implementation environment (for example, Spring). 34 * 35 * @since 0.2 36 */ 37 public class AopAllianceAnnotationsAuthorizingMethodInterceptor 38 extends AnnotationsAuthorizingMethodInterceptor implements MethodInterceptor { 39 40 public AopAllianceAnnotationsAuthorizingMethodInterceptor() { 41 List<AuthorizingAnnotationMethodInterceptor> interceptors = 42 new ArrayList<AuthorizingAnnotationMethodInterceptor>(5); 43 44 //use a Spring-specific Annotation resolver - Spring's AnnotationUtils is nicer than the 45 //raw JDK resolution process. 46 AnnotationResolver resolver = new SpringAnnotationResolver(); 47 //we can re-use the same resolver instance - it does not retain state: 48 interceptors.add(new RoleAnnotationMethodInterceptor(resolver)); 49 interceptors.add(new PermissionAnnotationMethodInterceptor(resolver)); 50 interceptors.add(new AuthenticatedAnnotationMethodInterceptor(resolver)); 51 interceptors.add(new UserAnnotationMethodInterceptor(resolver)); 52 interceptors.add(new GuestAnnotationMethodInterceptor(resolver)); 53 54 setMethodInterceptors(interceptors); 55 } 56 /** 57 * Creates a {@link MethodInvocation MethodInvocation} that wraps an 58 * {@link org.aopalliance.intercept.MethodInvocation org.aopalliance.intercept.MethodInvocation} instance, 59 * enabling Shiro Annotations in <a href="http://aopalliance.sourceforge.net/">AOP Alliance</a> environments 60 * (Spring, etc). 61 * 62 * @param implSpecificMethodInvocation AOP Alliance {@link org.aopalliance.intercept.MethodInvocation MethodInvocation} 63 * @return a Shiro {@link MethodInvocation MethodInvocation} instance that wraps the AOP Alliance instance. 64 */ 65 protected org.apache.shiro.aop.MethodInvocation createMethodInvocation(Object implSpecificMethodInvocation) { 66 final MethodInvocation mi = (MethodInvocation) implSpecificMethodInvocation; 67 68 return new org.apache.shiro.aop.MethodInvocation() { 69 public Method getMethod() { 70 return mi.getMethod(); 71 } 72 73 public Object[] getArguments() { 74 return mi.getArguments(); 75 } 76 77 public String toString() { 78 return "Method invocation [" + mi.getMethod() + "]"; 79 } 80 81 public Object proceed() throws Throwable { 82 return mi.proceed(); 83 } 84 85 public Object getThis() { 86 return mi.getThis(); 87 } 88 }; 89 } 90 91 /** 92 * Simply casts the method argument to an 93 * {@link org.aopalliance.intercept.MethodInvocation org.aopalliance.intercept.MethodInvocation} and then 94 * calls <code>methodInvocation.{@link org.aopalliance.intercept.MethodInvocation#proceed proceed}()</code> 95 * 96 * @param aopAllianceMethodInvocation the {@link org.aopalliance.intercept.MethodInvocation org.aopalliance.intercept.MethodInvocation} 97 * @return the {@link org.aopalliance.intercept.MethodInvocation#proceed() org.aopalliance.intercept.MethodInvocation.proceed()} method call result. 98 * @throws Throwable if the underlying AOP Alliance <code>proceed()</code> call throws a <code>Throwable</code>. 99 */ 100 protected Object continueInvocation(Object aopAllianceMethodInvocation) throws Throwable { 101 MethodInvocation mi = (MethodInvocation) aopAllianceMethodInvocation; 102 return mi.proceed(); 103 } 104 105 /** 106 * Creates a Shiro {@link MethodInvocation MethodInvocation} instance and then immediately calls 107 * {@link org.apache.shiro.authz.aop.AuthorizingMethodInterceptor#invoke super.invoke}. 108 * 109 * @param methodInvocation the AOP Alliance-specific <code>methodInvocation</code> instance. 110 * @return the return value from invoking the method invocation. 111 * @throws Throwable if the underlying AOP Alliance method invocation throws a <code>Throwable</code>. 112 */ 113 public Object invoke(MethodInvocation methodInvocation) throws Throwable { 114 org.apache.shiro.aop.MethodInvocation mi = createMethodInvocation(methodInvocation); 115 return super.invoke(mi); 116 } 117 }