<!-- 用来判断用户是否有权限执行方法的拦截器 --> <bean id="methodSecurityAdvice" class="cn.focus.dc.cms.auth.interceptor.MethodSecurityInterceptor"/> <aop:config proxy-target-class="true"> <aop:aspect id="methodSecurityAspect" ref="methodSecurityAdvice"> <aop:before pointcut="execution(public * cn.focus.dc.cms.auth.service..*.*(..))" method="permitCheck"/> </aop:aspect> </aop:config>
/** * 对于标注了RequiresPermissions的方法拦截 <br/> * 判断用户是否有标注的权限,如果没有抛出异常禁止执行方法 */ @Component public class MethodSecurityInterceptor { public void permitCheck(JoinPoint jp) { Method method = ((MethodSignature) jp.getSignature()).getMethod(); RequiresPermissions permission = method.getAnnotation(RequiresPermissions.class); if (null != permission) { Subject subject = SecurityUtils.getSubject(); String[] permits = permission.value(); for (String permit : permits) { subject.checkPermission(permit); } } } }
package org.apache.shiro.authz.annotation; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface RequiresPermissions { /** * The permission string which will be passed to {@link org.apache.shiro.subject.Subject#isPermitted(String)} * to determine if the user is allowed to invoke the code protected by this annotation. */ String[] value(); /** * The logical operation for the permission checks in case multiple roles are specified. AND is the default * @since 1.1.0 */ Logical logical() default Logical.AND; }
public * cn.focus.dc.cms.auth.service..*.*(..)
总结一下:
--------------------------------------------------------------------------------
1,pointcut既可以定义在一个接口上面(表示实现该接口的类方法将被拦截),同时也可以定义在一个类上面(无接口的情况,需要强制使用cglib)。在接口上面定义pointcut时无需关心接口实现类的具体位置,只需要定义被拦截的接口及方法位置。
2,常见的情况:
第一种情况:x.y.service..*Service.*(..)
x.y.service:表示包“x.y.service”
x.y.service.. :表示包“x.y.service”及其子包例如:“x.y.service.abc”,“x.y.service.def”,“x.y.service.ghi”,“x.y.service.jkl”。。。
*Service:定义接口(或没有实现接口的类,需要使用cglib代理)表达式;所有以Service结尾的类或接口,注意不是所有以Service结尾的包名。
*(..) :定义方法名,方法参数表达式;任意方法的名称,任意方法参数。
第二种情况:com.xyz.service.*.*(..)
com.xyz.service:定义 包“com.xyz.service”
*.*(..):定义任意接口(或没有实现接口的类,需要使用cglib代理),任意方法,任意参数在service包下定义的任意方法的执行。
第三种情况:com.xyz.service..*.*(..)
com.xyz.service:定义 包“com.xyz.service”
com.xyz.service.. :定义包“com.xyz.service”及其子包
*.*(..):定义任意接口(或没有实现接口的类,需要使用cglib代理),任意方法,任意参数.