Shiro权限注解原理(3)

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) {
            if (ae.getCause() == null) ae.initCause(new AuthorizationException("Not authorized to invoke method: " + mi.getMethod()));
            throw ae;
        }       
    }
}

现在分析其中一种实现类PermissionAnnotationMethodInterceptor,也是用的最多的,但是这个类的实际代码很少,很明显上述分析的getHandler在PermissionAnnotationMethodInterceptor中返回值为PermissionAnnotationHandler。
public class PermissionAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {

public PermissionAnnotationMethodInterceptor() {
        super( new PermissionAnnotationHandler() );
    }


    public PermissionAnnotationMethodInterceptor(AnnotationResolver resolver) {
        super( new PermissionAnnotationHandler(), resolver);
    }
}

在PermissionAnnotationHandler类中,终于发现实际的检验逻辑,还是调用的Subject.checkPermission()进行校验。
public class PermissionAnnotationHandler extends AuthorizingAnnotationHandler {

public PermissionAnnotationHandler() {
        super(RequiresPermissions.class);
    }

protected String[] getAnnotationValue(Annotation a) {
        RequiresPermissions rpAnnotation = (RequiresPermissions) a;
        return rpAnnotation.value();
    }

public void assertAuthorized(Annotation a) throws AuthorizationException {
        if (!(a instanceof RequiresPermissions)) return;

RequiresPermissions rpAnnotation = (RequiresPermissions) a;
        String[] perms = getAnnotationValue(a);
        Subject subject = getSubject();

if (perms.length == 1) {
            subject.checkPermission(perms[0]);
            return;
        }
        if (Logical.AND.equals(rpAnnotation.logical())) {
            getSubject().checkPermissions(perms);
            return;
        }
        if (Logical.OR.equals(rpAnnotation.logical())) {
            boolean hasAtLeastOnePermission = false;
            for (String permission : perms) if (getSubject().isPermitted(permission)) hasAtLeastOnePermission = true;
            if (!hasAtLeastOnePermission) getSubject().checkPermission(perms[0]);
           
        }
    }
}

3|0实现类似编程式AOP

定义一个注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";
}

继承StaticMethodMatcherPointcutAdvisor类,并实现相关的方法。
@SuppressWarnings("serial")
@Component
public class HelloAdvisor extends StaticMethodMatcherPointcutAdvisor{
   
    public HelloAdvisor() {
        setAdvice(new LogMethodInterceptor());
    }

public boolean matches(Method method, Class targetClass) {
        Method m = method;
        if ( isAuthzAnnotationPresent(m) ) {
            return true;
        }

if ( targetClass != null) {
            try {
                m = targetClass.getMethod(m.getName(), m.getParameterTypes());
                return isAuthzAnnotationPresent(m);
            } catch (NoSuchMethodException ignored) {
             
            }
        }
        return false;
    }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/ca6c012f65e13e14787202e4142b4069.html