aop:config在shiro权限注解中发挥的作用

问题

spring-shiro.xml中通常会加aop配置,以使shiro认证注解(@RequiresPermissions、@RequiresRoles、@RequiresUser、@RequiresGuest)work。
通常配置如下

<aop:config />
    <!--权限注解的advisor -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>

但是我有一个问题!<aop:config/>没有配置通知,也没有配置切点,shiro的认证注解怎么就work了呢?

AuthorizationAttributeSourceAdvisor

我们注意到有个AuthorizationAttributeSourceAdvisor配置,它是一个通知器
类层次图
这里写图片描述

观察类层次结构图,可以看到它实现了pointcut,我们知道pointcut就是切点,它会判断匹配哪些类,并返回方法匹配

public interface Pointcut {

    /**
     * Return the ClassFilter for this pointcut.
     * @return the ClassFilter (never {@code null})
     */
    ClassFilter getClassFilter();

    /**
     * Return the MethodMatcher for this pointcut.
     * @return the MethodMatcher (never {@code null})
     */
    MethodMatcher getMethodMatcher();


    /**
     * Canonical Pointcut instance that always matches.
     */
    Pointcut TRUE = TruePointcut.INSTANCE;

}

pointcut中一共两个接口方法,一个是getClassFilter,一个是getMethodMatcher

getClassFilter匹配所有类

AuthorizationAttributeSourceAdvisor的父类StaticMethodMatcherPointcut中,实现了getClassFiltergetMethodMatcher方法。

public abstract class StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut {

    private ClassFilter classFilter = ClassFilter.TRUE;


    /**
     * Set the {@link ClassFilter} to use for this pointcut.
     * Default is {@link ClassFilter#TRUE}.
     */
    public void setClassFilter(ClassFilter classFilter) {
        this.classFilter = classFilter;
    }

    @Override
    public ClassFilter getClassFilter() {
        return this.classFilter;
    }


    @Override
    public final MethodMatcher getMethodMatcher() {
        return this;
    }

}

继续追踪,类属性classFilter是ClassFilter.TRUE,最终跟踪到TrueClassFilter,matches方法始终返回true,所以AuthorizationAttributeSourceAdvisor匹配所有类

class TrueClassFilter implements ClassFilter, Serializable {

    public static final TrueClassFilter INSTANCE = new TrueClassFilter();

    /**
     * Enforce Singleton pattern.
     */
    private TrueClassFilter() {
    }

    @Override
    public boolean matches(Class<?> clazz) {
        return true;
    }
}

getMethodMatcher匹配所有加了认证注解的方法

再看方法匹配,注意StaticMethodMatcherPointcutgetMethodMatcher返回的是this,因为AuthorizationAttributeSourceAdvisor实现了MethodMatcher接口,所以返回的this就是AuthorizationAttributeSourceAdvisor本身。MethodMatchermatches方法用来判断方法匹配。
可以看到它会匹配所有加了认证注解的方法。

 AuthorizationAttributeSourceAdvisor.java

 private static final Class<? extends Annotation>[] AUTHZ_ANNOTATION_CLASSES =
            new Class[] {
                    RequiresPermissions.class, RequiresRoles.class,
                    RequiresUser.class, RequiresGuest.class, RequiresAuthentication.class
            };
 public boolean matches(Method method, Class targetClass) {
        Method m = method;

        if ( isAuthzAnnotationPresent(m) ) {
            return true;
        }

        //The 'method' parameter could be from an interface that doesn't have the annotation.
        //Check to see if the implementation has it.
        if ( targetClass != null) {
            try {
                m = targetClass.getMethod(m.getName(), m.getParameterTypes());
                if ( isAuthzAnnotationPresent(m) ) {
                    return true;
                }
            } catch (NoSuchMethodException ignored) {
                //default return value is false.  If we can't find the method, then obviously
                //there is no annotation, so just use the default return value.
            }
        }

        return false;
    }

 private boolean isAuthzAnnotationPresent(Method method) {
        for( Class<? extends Annotation> annClass : AUTHZ_ANNOTATION_CLASSES ) {
            Annotation a = AnnotationUtils.findAnnotation(method, annClass);
            if ( a != null ) {
                return true;
            }
        }
        return false;
    }

aop:config

至今,我们有了一个完整的切面认识AuthorizationAttributeSourceAdvisor

  • 匹配所有类
  • 匹配所有加认证注解的方法

我们知道,<aop:config/>会扫描配置文件中的所有advisor,并为其创建代理。正是有个<aop:config/>加上AuthorizationAttributeSourceAdvisor,所以认证注解才会work

总结

至此,我们就明白了,正是有了以下两条的作用,才使得shiro认证注解可以正常work。

  • <aop:config/>会扫描配置文件中的所有advisor,并为其创建代理
  • AuthorizationAttributeSourceAdvisor匹配所有类,匹配所有加了认证注解的方法
  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值