您的位置:首页 > 运维架构

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

2016-07-12 15:43 1036 查看

问题

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
中,实现了
getClassFilter
getMethodMatcher
方法。

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匹配所有加了认证注解的方法

再看方法匹配,注意
StaticMethodMatcherPointcut
getMethodMatcher
返回的是this,因为
AuthorizationAttributeSourceAdvisor
实现了
MethodMatcher
接口,所以返回的this就是
AuthorizationAttributeSourceAdvisor
本身。
MethodMatcher
matches方法用来判断方法匹配。

可以看到它会匹配所有加了认证注解的方法。

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
匹配所有类,匹配所有加了认证注解的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: