简介
Spring Shiro框架对接口MethodInterceptor的实现,主要用于校验当前Subject在被允许继续访问前,是否有能力执行方法;
核心代码
/**
* 执行方法
* 允许前置处理/后置处理/最终处理
*/
Object invoke(MethodInvocation methodInvocation) throws Throwable;
实现子类
实现类如下:
public interface MethodInterceptor
abstract class MethodInterceptorSupport
abstract class AnnotationMethodInterceptor
abstract class AuthorizingAnnotationMethodInterceptor
class UserAnnotationMethodInterceptor
class PermissionAnnotationMethodInterceptor
class GuestAnnotationMethodInterceptor
class RoleAnnotationMethodInterceptor
class AuthenticatedAnnotationMethodInterceptor
abstract class AuthorizingMethodInterceptor
abstract class AnnotationsAuthorizingMethodInterceptor
class AopAllianceAnnotationsAuthorizingMethodInterceptor
简介
特定于Spring Shiro框架中AOP方法拦截器行为的抽象,将AOP处理细节留给子类实现;本类提供获取当前Subject的方法;
核心代码
/**
* 构造方法
*/
public MethodInterceptorSupport() {
// 默认无参构造方法
}
/**
* 获取当前Subject
*/
protected Subject getSubject() {
// 默认通过Shiro框架提供的方式获取当前Subject
return SecurityUtils.getSubject();
}
-
AnnotationMethodInterceptor
简介
在被拦截的方法调用之前检查方法上特定的注解;
核心代码
// 注解处理器
private AnnotationHandler handler;
// 注解解析器
private AnnotationResolver resolver;
/**
* 构造函数
*/
public AnnotationMethodInterceptor(AnnotationHandler handler, AnnotationResolver resolver) {
if (handler == null) {
// 必须指定注解处理器
throw new IllegalArgumentException("AnnotationHandler argument cannot be null.");
}
setHandler(handler);
// 注解解析器不存在则默认为DefaultAnnotationResolver
setResolver(resolver != null ? resolver : new DefaultAnnotationResolver());
}
/**
* 是否拦截指定的MethodInvocation
*/
public boolean supports(MethodInvocation mi) {
// 是否存在本拦截器关心的注解
return getAnnotation(mi) != null;
}
/**
* 获取本拦截器关心的注解
*/
protected Annotation getAnnotation(MethodInvocation mi) {
return getResolver().getAnnotation(mi, getHandler().getAnnotationClass());
}
-
AuthorizingAnnotationMethodInterceptor
简介
通过检查方法上的注解,在方法执行之前校验当前Subject是否被授权执行该方法;
核心代码
/**
* 执行方法
*/
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
// 在方法调用前进行授权校验
assertAuthorized(methodInvocation);
return methodInvocation.proceed();
}
/**
* 校验授权
*/
public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
try {
// 由注解处理器进行授权检查
((AuthorizingAnnotationHandler)getHandler()).assertAuthorized(getAnnotation(mi));
}
catch(AuthorizationException ae) {
// Annotation handler doesn't know why it was called, so add the information here if possible.
// Don't wrap the exception here since we don't want to mask the specific exception, such as
// UnauthenticatedException etc.
if (ae.getCause() == null) ae.initCause(new AuthorizationException("Not authorized to invoke method: " + mi.getMethod()));
throw ae;
}
}
-
AuthenticatedAnnotationMethodInterceptor
简介
检查被拦截方法是否声明注解RequiresAuthenticated,如果声明,校验当前Subject在执行该方法前,已登录;
核心代码
/**
* 构造方法
*/
public AuthenticatedAnnotationMethodInterceptor() {
super(new AuthenticatedAnnotationHandler());
}
/**
* 构造方法
*/
public AuthenticatedAnnotationMethodInterceptor(AnnotationResolver resolver) {
super(new AuthenticatedAnnotationHandler(), resolver);
}
-
GuestAnnotationMethodInterceptor
简介
检查被拦截方法是否声明注解RequiresGuest,如果声明,校验当前Subject在执行该方法前,未登录;
核心代码
/**
* 构造方法
*/
public GuestAnnotationMethodInterceptor() {
super(new GuestAnnotationHandler());
}
/**
* 构造方法
*/
public GuestAnnotationMethodInterceptor(AnnotationResolver resolver) {
super(new GuestAnnotationHandler(), resolver);
}
-
UserAnnotationMethodInterceptor
简介
检查被拦截方法是否声明注解RequiresUser,如果声明,校验当前Subject在执行该方法前,已登录或者被记住;
核心代码
/**
* 构造方法
*/
public UserAnnotationMethodInterceptor() {
super( new UserAnnotationHandler() );
}
/**
* 构造方法
*/
public UserAnnotationMethodInterceptor(AnnotationResolver resolver) {
super(new UserAnnotationHandler(), resolver);
}
-
PermissionAnnotationMethodInterceptor
简介
检查被拦截方法是否声明注解RequiresPermissions,如果声明,校验当前Subject在执行该方法前,是否拥有指定的权限列表;
核心代码
/**
* 构造方法
*/
public PermissionAnnotationMethodInterceptor() {
super( new PermissionAnnotationHandler() );
}
/**
* 构造方法
*/
public PermissionAnnotationMethodInterceptor(AnnotationResolver resolver) {
super( new PermissionAnnotationHandler(), resolver);
}
-
RoleAnnotationMethodInterceptor
简介
检查被拦截方法是否声明注解RequiresRoles,如果声明,校验当前Subject在执行该方法前,是否拥有指定的角色列表;
核心代码
/**
* 构造方法
*/
public RoleAnnotationMethodInterceptor() {
super( new RoleAnnotationHandler() );
}
/**
* 构造方法
*/
public RoleAnnotationMethodInterceptor(AnnotationResolver resolver) {
super(new RoleAnnotationHandler(), resolver);
}
-
AuthorizingMethodInterceptor
简介
支持拦截方法进行授权校验的基础抽象类;
核心代码
/**
* 执行方法
*/
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
// 在方法执行前进行授权校验
assertAuthorized(methodInvocation);
return methodInvocation.proceed();
}
/**
* 校验授权
* 由子类实现算法细节
*/
protected abstract void assertAuthorized(MethodInvocation methodInvocation) throws AuthorizationException;
-
AnnotationsAuthorizingMethodInterceptor
简介
基于多个配置的AuthorizingAnnotationMethodInterceptor校验当前Subject是否被授权执行该方法;如果有一个AuthorizingAnnotationMethodInterceptor校验失败,则当前Subject无法执行该方法;
本质上是一种允许单个方法拦截器处理多个注解的便利机制;
核心代码
// AuthorizingAnnotationMethodInterceptor集合
protected Collection<AuthorizingAnnotationMethodInterceptor> methodInterceptors;
/**
* 构造函数
* 默认拥有多个AuthorizingAnnotationMethodInterceptor
*/
public AnnotationsAuthorizingMethodInterceptor() {
methodInterceptors = new ArrayList<AuthorizingAnnotationMethodInterceptor>(5);
methodInterceptors.add(new RoleAnnotationMethodInterceptor());
methodInterceptors.add(new PermissionAnnotationMethodInterceptor());
methodInterceptors.add(new AuthenticatedAnnotationMethodInterceptor());
methodInterceptors.add(new UserAnnotationMethodInterceptor());
methodInterceptors.add(new GuestAnnotationMethodInterceptor());
}
/**
* 校验授权
*/
protected void assertAuthorized(MethodInvocation methodInvocation) throws AuthorizationException {
//default implementation just ensures no deny votes are cast:
Collection<AuthorizingAnnotationMethodInterceptor> aamis = getMethodInterceptors();
if (aamis != null && !aamis.isEmpty()) {
// 遍历配置的AuthorizingAnnotationMethodInterceptor
for (AuthorizingAnnotationMethodInterceptor aami : aamis) {
if (aami.supports(methodInvocation)) {
// 校验授权
aami.assertAuthorized(methodInvocation);
}
}
}
}
-
AopAllianceAnnotationsAuthorizingMethodInterceptor
简介
适配任何AOP环境,将基于AOP的MethodInvocation包装为Spring Shiro框架的MethodInvocation;
核心代码
/**
* 构造函数
*/
public AopAllianceAnnotationsAuthorizingMethodInterceptor() {
List<AuthorizingAnnotationMethodInterceptor> interceptors = new ArrayList(5);
AnnotationResolver resolver = new SpringAnnotationResolver();
interceptors.add(new RoleAnnotationMethodInterceptor(resolver));
interceptors.add(new PermissionAnnotationMethodInterceptor(resolver));
interceptors.add(new AuthenticatedAnnotationMethodInterceptor(resolver));
interceptors.add(new UserAnnotationMethodInterceptor(resolver));
interceptors.add(new GuestAnnotationMethodInterceptor(resolver));
// 默认拥有多个AuthorizingAnnotationMethodInterceptor
this.setMethodInterceptors(interceptors);
}
/**
* 将基于AOP的MethodInvocation包装为Shiro的MethodInvocation
*/
protected org.apache.shiro.aop.MethodInvocation createMethodInvocation(Object implSpecificMethodInvocation) {
final MethodInvocation mi = (MethodInvocation) implSpecificMethodInvocation;
return new org.apache.shiro.aop.MethodInvocation() {
public Method getMethod() {
return mi.getMethod();
}
public Object[] getArguments() {
return mi.getArguments();
}
public String toString() {
return "Method invocation [" + mi.getMethod() + "]";
}
public Object proceed() throws Throwable {
return mi.proceed();
}
public Object getThis() {
return mi.getThis();
}
};
}
/**
* 继续调用
*/
protected Object continueInvocation(Object aopAllianceMethodInvocation) throws Throwable {
org.aopalliance.intercept.MethodInvocation mi = (org.aopalliance.intercept.MethodInvocation)aopAllianceMethodInvocation;
return mi.proceed();
}
|