Shiro 权限验证原理

概要

实现权限验证行为的前提需要实现横切拦截设计(Spring的AOP)参考:https://www.cnblogs.com/BINGJJFLY/p/9066524.html

spring-shiro.xml配置文件的配置

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">  
    <property name="proxyTargetClass" value="true"/>
</bean>  
  
<bean id="authorizationAttributeSourceAdvisor" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
    <property name="securityManager" ref="securityManager" />  
</bean>

AuthorizationAttributeSourceAdvisor

public AuthorizationAttributeSourceAdvisor() {
    setAdvice(new AopAllianceAnnotationsAuthorizingMethodInterceptor());
}

AopAllianceAnnotationsAuthorizingMethodInterceptor

public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    assertAuthorized(methodInvocation);
    return methodInvocation.proceed();
}

获得各个方法拦截器如RoleAnnotationMethodInterceptor

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()) {
        for (AuthorizingAnnotationMethodInterceptor aami : aamis) {
            if (aami.supports(methodInvocation)) {
                aami.assertAuthorized(methodInvocation);
            }
        }
    }
}

RoleAnnotationMethodInterceptor

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;
    }         
} 

RoleAnnotationHandler

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

    RequiresRoles rrAnnotation = (RequiresRoles) a;
    String[] roles = rrAnnotation.value();

    if (roles.length == 1) {
     // 获得WebDelegatingSubject校验会员角色权限 getSubject().checkRole(roles[
0]); return; } if (Logical.AND.equals(rrAnnotation.logical())) { getSubject().checkRoles(Arrays.asList(roles)); return; } if (Logical.OR.equals(rrAnnotation.logical())) { // Avoid processing exceptions unnecessarily - "delay" throwing the exception by calling hasRole first boolean hasAtLeastOneRole = false; for (String role : roles) if (getSubject().hasRole(role)) hasAtLeastOneRole = true; // Cause the exception if none of the role match, note that the exception message will be a bit misleading if (!hasAtLeastOneRole) getSubject().checkRole(roles[0]); } }

DelegatingSubject专门校验会员权限

Subject校验权限 --> SecurityManager校验权限 --> Realm校验权限

public void checkRole(String role) throws AuthorizationException {
    assertAuthzCheckPossible();
// getPrincipals()获得会员存储在数据库的信息 securityManager.checkRole(getPrincipals(), role); }

SecurityManager校验权限

猜你喜欢

转载自www.cnblogs.com/BINGJJFLY/p/9107899.html