Spring Security 3 基於角色訪問控制過程詳解 .

訪問控制:

由於我們配置了訪問控制(授權)的默認攔截器org.springframework.security.web.access.intercept.FilterSecurityInterceptor。其主要業務方法是InterceptorStatusToken beforeInvocation(Object object)


該方法會將URL傳給SecurityMetadataSource獲取匹配該URL所有參數ConfigAttribute(擁有權限的角色)的集合。


如果該用戶尚未認證(登錄),或攔截器配置了“始終認證”,則攔截器會將該用戶的登錄信息(未登錄則跳轉到登陸頁面)重新認證,並加載角色信息。


隨後將用戶認證信息(Authentication),用戶請求訪問的URL,以及配置集合(Collection<ConfigAttribute>)交由accessDecisionManager的decide方法。通過則方法繼續,否則拋出AccessDeniedException。


調用runAsManager嘗試轉換認證信息,這是爲了方便適應兩層訪問控制架構。runAsManager就可以將外部公開的認證,轉換爲內部認證,繼續之後的訪問。


之後返回包含訪問攔截信息的對象InterceptorStatusToken。以便afterInvocation(InterceptorStatusToken, Object)方法運行。


安全信息元數據提供者:


默認實現DefaultFilterInvocationSecurityMetadataSource構造時通過addSecureUrl(String pattern, String method, Collection<ConfigAttribute> attrs)方法將傳入參數轉換爲私有成員變量Map<String, Map<Object, Collection<ConfigAttribute>>> httpMethodMap緩存,並通過Collection<ConfigAttribute> lookupAttributes(String url, String method)獲得第一個能匹配的上的URL模式,並返回其所需要的角色集合Collection<ConfigAttribute>

訪問控制管理者:


訪問控制管理者AccessDecisionManager需要投票者AccessDecisionVoter列表,調用後者的vote方法。而前者則負責統計所有投票者的投票情況,並做出是否授權的決定。而框架提供了三個統計策略,分別是“只要有一個投票者同意即同意”,“需要所有投票者同意才同意”,“少數服從多數”。分別對應着

AbstractAccessDecisionManager的三個子類AffirmativeBased, UnanimousBased,ConsensusBased。


基於角色的投票者


RoleVoter實現了AccessDecisionVoter接口,其vote方法是這樣寫的。
  1. public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {  
  2.         int result = ACCESS_ABSTAIN;  
  3.         Collection<GrantedAuthority> authorities = extractAuthorities(authentication);  
  4.   
  5.   
  6.         for (ConfigAttribute attribute : attributes) {  
  7.             if (this.supports(attribute)) {  
  8.                 result = ACCESS_DENIED;  
  9.   
  10.   
  11.                 // 查找匹配角色   
  12.                 for (GrantedAuthority authority : authorities) {  
  13.                     if (attribute.getAttribute().equals(authority.getAuthority())) {  
  14.                         return ACCESS_GRANTED;  
  15.                     }  
  16.                 }  
  17.             }  
  18.         }  
  19.   
  20.   
  21.         return result;  
  22.     }  
  23.   
  24.   
  25. Collection<GrantedAuthority> extractAuthorities(Authentication authentication) {  
  26.         return authentication.getAuthorities();  
  27.     }  
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
        int result = ACCESS_ABSTAIN;
        Collection<GrantedAuthority> authorities = extractAuthorities(authentication);


        for (ConfigAttribute attribute : attributes) {
            if (this.supports(attribute)) {
                result = ACCESS_DENIED;


                // 查找匹配角色
                for (GrantedAuthority authority : authorities) {
                    if (attribute.getAttribute().equals(authority.getAuthority())) {
                        return ACCESS_GRANTED;
                    }
                }
            }
        }


        return result;
    }


Collection<GrantedAuthority> extractAuthorities(Authentication authentication) {
        return authentication.getAuthorities();
    }




ps:DefaultFilterInvocationSecurityMetadataSource初始化過程詳解


Spring Security 3 訪問驗證模塊的初始化,主要是FilterInvocationSecurityMetadataSource對象加載配置信息的過程。

而FilterInvocationSecurityMetadataSource的實現,我選用了框架提供的默認實現DefaultFilterInvocationSecurityMetadataSource。

在DefaultFilterInvocationSecurityMetadataSource 構造的時候,需要UrlMatcher和LinkedHashMap<RequestKey, Collection<ConfigAttribute>>兩個參數。
前者是解析Url的匹配器,框架提供兩種選擇:一個是AntUrlPathMatcher,另一個是正則匹配。當然也可以自己寫,只要實現UrlMatcher接口就行。
第二個參數需要提供 所有的請求URL模板,與其對應所有的配置屬性(在RBAC系統中即爲“角色碼”)。

例如:RequestKey爲 /user!add**, Collection<ConfigAttribute>爲[ROLE_HR, ROLE_ADMIN]。就是說,能有權限訪問用戶添加模塊的角色爲HR,和管理員。


在DefaultFilterInvocationSecurityMetadataSource 的構造方法當中,其通過addSecureUrl(String pattern, String method, Collection<ConfigAttribute> attrs)方法將傳入參數轉換爲私有成員變量Map<String, Map<Object, Collection<ConfigAttribute>>> httpMethodMap;
key是Http方法:主要“GET”"和POST",Value是Key的HTTP方法對應的配置屬性集合。key爲null時,value爲不特定方法的配置屬性集合。而Value也是一個Map,它的主鍵是編譯後的URL模板,值爲各種角色的ConfigAttribute對象。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章