首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 原始碼解析(十):Spring Security (Acegi) 授權機制深度剖析

     編輯:Java 相關知識

授權入口:FilterSecurityInterceptor

HTTP 請求經 FilterSecurityInterceptor.doFilter() 攔截,封裝為 FilterInvocation 呼叫 invoke()。首次請求設定 FILTER_APPLIED 屬性避免重複檢查,隨後呼叫父類 AbstractSecurityInterceptor.beforeInvocation() 執行核心授權邏輯。

AbstractSecurityInterceptor 授權流程

  1. 取得資源安全屬性:透過 ObjectDefinitionSource 讀取配置的 ConfigAttributeDefinition(如角色要求)。若為 null 且 rejectPublicInvocations=true 則拒絕存取。
  2. 取得/建立 Authentication:從 SecurityContextHolder 取得 Authentication。若不存在或未認證,委派 AuthenticationManager 認證,成功後存回 SecurityContextHolder。
  3. 授權決策:呼叫 AccessDecisionManager.decide(authentication, object, attr)。失敗拋 AccessDeniedException 並發布 AuthorizationFailureEvent;成功發布 AuthorizedEvent。
  4. RunAs 機制:透過 RunAsManager 可替換當前 Authentication(預設 NullRunAsManager 清空)。返回 InterceptorStatusToken 供 afterInvocation 使用。

AccessDecisionManager 實作:AffirmativeBased

預設決策管理器遍歷配置的 AccessDecisionVoter 投票:

  • 任一投票者返回 ACCESS_GRANTED → 立即通過。
  • 返回 ACCESS_DENIED → 計數,最終若有反對票則拋出異常。
  • 全為 ACCESS_ABSTAIN → 依 allowIfAllAbstainDecisions 決定(預設拒絕)。

核心投票者:RoleVoter

遍歷資源配置屬性,支援 ROLE_ 前綴角色。檢查使用者 GrantedAuthority[] 中是否包含匹配角色,若有則返回 ACCESS_GRANTED,否則 ACCESS_DENIED。若無支援屬性則棄權。

public int vote(Authentication auth, Object obj, ConfigAttributeDefinition config) {
    int result = ACCESS_ABSTAIN;
    for (ConfigAttribute attr : config.getConfigAttributes()) {
        if (supports(attr)) {
            result = ACCESS_DENIED;
            for (GrantedAuthority ga : auth.getAuthorities()) {
                if (attr.getAttribute().equals(ga.getAuthority()))
                    return ACCESS_GRANTED;
            }
        }
    }
    return result;
}

總結

授權流程:FilterSecurityInterceptor 攔截 → 讀取資源屬性 → 確保認證 → AccessDecisionManager 協調多 Voter 投票 → RoleVoter 基於角色匹配決策 → 發布事件/處理 RunAs。架構清晰分離攔截、認證、授權、決策、投票職責,支援靈活擴展。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved