亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

Spring Security 在 Servlet 請求中實現鑒權

1. 前言

Servlet 是 Java Web 應用的最常見場景,Spring Security 對 Servlet 的權限認定過程實現了規范化和流程化。

本節主要討論在 Servlet 應用中,如何通過 Spring Security 實現鑒權。

2. Servlet 權限控制的流程

Servlet 鑒權主要圍繞著 FilterSecurityInterceptor 類展開,該類作為一個安全過濾器,被放置在 FilterChainProxy 中。

圖片描述

圖 1. Servlet 請求鑒權流程

具體流程如下:

  1. FilterSecurityInterceptorSecurityContextHolder 中獲取 Authentication 對象;
  2. FilterSecurityInterceptorHttpServletRequest、HttpServletREsponseFilterChain 中創建 FilterInvocation 對象;
  3. 將創建的 FilterInvocation 對象傳遞給 SecurityMetadataSource 用來獲取 ConfigAttribute 對象集合;
  4. 最后,將 Authentication、FilterInvocationConfigAttribute 對象傳遞給 AccessDecisionManager 實例驗證權限:
    • 如果驗證失敗,將拋出 AccessDeniedException 異常,并由 ExceptionTranslationFilter 接收并處理;
    • 如果驗證通過,FilterSecurityInterceptor 將控制權交還給 FilterChain,使程序繼續執行。

3. Servlet 權限控制的配置實現

默認情況下,Spring Security 的權限要求所有的請求都需要首先通過認證。相當于以下配置描述:

protected void configure(HttpSecurity http) throws Exception {
    http
        // ...
        .authorizeRequests(authorize -> authorize
            .anyRequest().authenticated()
        );
}

如果我們需要配置 Spring Security 對不同請求有不同的處理規則時,可通過以下方式修改配置:

protected void configure(HttpSecurity http) throws Exception {
    http
        // ...
        .authorizeRequests(authorize -> authorize                                  
            .mvcMatchers("/resources/**", "/signup", "/about").permitAll()         
            .mvcMatchers("/admin/**").hasRole("ADMIN")                             
            .mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")   
            .anyRequest().denyAll()                                                
        );
}

以上這段代碼實現了如下功能:

  1. 指定了多種規則,每種規則按照其配置的順序決定優先級;
  2. 匹配了多個 URL 規則,對于 /resources、/signup、/about 允許任何用戶訪問;
  3. 任何以 /admin/ 開頭的地址都要求用戶具有管理員權限 ROLE_ADMIN,其中 ROLE_ 前綴是 Spring Security 默認添加的,用戶無需做特殊處理;
  4. 任何以 /db/ 為開頭的地址需要同時擁有 ROLE_ADMINROLE_DBA 角色;
  5. 沒有被上述 URL 地址匹配的地址都將被禁止訪問,加上這一條非常有助于提升系統的安全性。

4. 小結

本節討論了如何用 Spring Security 規范化 Servlet 鑒權過程:

  • Spring Security 對 Servlet 請求的權限控制,主要依賴于 FilterSecurityInterceptor 實現;
  • Spring Security 默認對每一個 Servlet 請求都要求用戶已通過認證;
  • Spring Security 支持對 Servlet 的不同 URL 規則配置不同的權限規則。

下節我們討論如何通過「訪問控制表達式」實現多樣化的鑒權規則。