91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Tomcat容器的安全認證和鑒權講解

發布時間:2021-09-13 14:14:43 來源:億速云 閱讀:168 作者:chen 欄目:服務器

本篇內容主要講解“Tomcat容器的安全認證和鑒權講解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Tomcat容器的安全認證和鑒權講解”吧!

1. 授權

容器和 Web 應用采用的是基于角色的權限訪問控制方式,其中容器需要實現認證和鑒權的功能,而 Web 應用則要實現授權的功能。

在 Servlet 規范中描述了兩種授權方式:聲明式安全和編程式安全。聲明式安全就是在部署描述符中聲明角色、資源訪問權限和認證方式。以下代碼片段摘自  Tomcat 自帶的 Manager 應用的 web.xml:

<security-constraint> <!-- 安全約束 -->   <web-resource-collection> <!-- 限制訪問的資源集合 -->     <web-resource-name>HTML Manager commands</web-resource-name>     <url-pattern>/html/*</url-pattern>   </web-resource-collection>   <auth-constraint><!-- 授權可訪問此資源集合的角色 -->      <role-name>manager-gui</role-name>   </auth-constraint> </security-constraint>  <login-config><!-- 配置驗證方法 -->   <auth-method>BASIC</auth-method>   <realm-name>Tomcat Manager Application</realm-name> </login-config>  <security-role><!-- 定義一個安全角色 -->   <description>     The role that is required to access the HTML Manager pages   </description>   <role-name>manager-gui</role-name> </security-role>

這些安全相關的配置,都會在應用部署時,初始化和設置到 StandardContext 對象中。更多詳細的內容可查看規范對部署描述文件的解釋,接下來看  Tomcat 怎么設計和實現認證及鑒權。

2. 認證和鑒權的設計

Servlet 規范雖然描述了 Web 應用聲明安全約束的機制,但沒有定義容器與關聯用戶和角色信息之間的接口。因此,Tomcat 定義了一個 Realm  接口,用于適配身份驗證的各種信息源。整體設計的類圖如下:

Tomcat容器的安全認證和鑒權講解

上圖中,包含了各個類的核心方法,關鍵類或接口的作用如下:

  • Realm -  譯為域,域有泛指某種范圍的意思,在這個范圍內存儲著用戶名、密碼、角色和權限,并且提供身份和權限驗證的功能,典型的這個范圍可以是某個配置文件或數據庫

  • CombinedRealm - 內部包含一個或多個 Realm,按配置順序執行身份驗證,任一 Realm 驗證成功,則表示成功驗證

  • LockOutRealm - 提供用戶鎖定機制,防止在一定時間段有過多身份驗證失敗的嘗試

  • Authenticator - 不同身份驗證方法的接口,主要有 BASIC、DIGEST、FORM、SSL 這幾種標準實現

  • Principal - 對認證主體的抽象,它包含用戶身份和權限信息

  • SingleSignOn - 用于支持容器內多應用的單點登錄功能

2.1 初始化

Realm 是容器的一個可嵌套組件,可以嵌套在 Engine、Host 和 Context 中,并且子容器可以覆蓋父容器配置的 Realm。默認的  server.xml 在 Engine 中配置了一個 LockOutRealm 組合域,內部包含一個 UserDatabaseRealm,它從配置的全局資源  conf/tomcat-users.xml 中提取用戶信息。

web.xml 中聲明的安全約束會初始化成對應的 SecurityConstraint、SecurityCollection 和 LoginConfig  對象,并關聯到一個 StandardContext 對象。

在上圖可以看到,AuthenticatorBase 還實現了 Valve 接口,StandardContext  對象在配置的過程中,如果發現聲明了標準的驗證方法,那么就會把它加入到自己的 Pipeline 中。

3. 一次請求認證和鑒權過程

Context 在 Tomcat 內部就代表著一個 Web 應用,假設配置使用 BASIC 驗證方法,那么 Context 內部的 Pipeline 就有  BasicAuthenticator 和 StandardContextValve 兩個閥門,當請求進入 Context  管道時,就首先進行認證和鑒權,方法調用如下:

Tomcat容器的安全認證和鑒權講解

整個過程的核心代碼就在 AuthenticatorBase 的 invoke 方法中:

public void invoke(Request request, Response response) throws IOException, ServletException {   LoginConfig config = this.context.getLoginConfig();   // 0. Session 對象中是否緩存著一個已經進行身份驗證的 Principal   if (cache) {     Principal principal = request.getUserPrincipal();     if (principal == null) {       Session session = request.getSessionInternal(false);       if (session != null) {         principal = session.getPrincipal();         if (principal != null) {           request.setAuthType(session.getAuthType());           request.setUserPrincipal(principal);         }       }     }   }   // 對于基于表單登錄,可能位于安全域之外的特殊情況進行處理   String contextPath = this.context.getPath();   String requestURI = request.getDecodedRequestURI();   if (requestURI.startsWith(contextPath) && requestURI.endsWith(Constants.FORM_ACTION)) {           return;       }   }   // 獲取安全域對象,默認配置是 LockOutRealm   Realm realm = this.context.getRealm();   // 根據請求 URI 嘗試獲取配置的安全約束   SecurityConstraint [] constraints = realm.findSecurityConstraints(request, this.context);     if ((constraints == null) /* && (!Constants.FORM_METHOD.equals(config.getAuthMethod())) */ ) {     // 為 null 表示訪問的資源沒有安全約束,直接訪問下一個閥門     getNext().invoke(request, response);     return;   }   // 確保受約束的資源不會被 Web 代理或瀏覽器緩存,因為緩存可能會造成安全漏洞   if (disableProxyCaching &&        !"POST".equalsIgnoreCase(request.getMethod())) {       if (securePagesWithPragma) {           response.setHeader("Pragma", "No-cache");           response.setHeader("Cache-Control", "no-cache");       } else {           response.setHeader("Cache-Control", "private");       }       response.setHeader("Expires", DATE_ONE);   }   int i;   // 1. 檢查用戶數據的傳輸安全約束   if (!realm.hasUserDataPermission(request, response, constraints)) {     // 驗證失敗     // Authenticator已經設置了適當的HTTP狀態代碼,因此我們不必做任何特殊的事情     return;   }   // 2. 檢查是否包含授權約束,也就是角色驗證   boolean authRequired = true;   for(i=0; i < constraints.length && authRequired; i++) {     if(!constraints[i].getAuthConstraint()) {       authRequired = false;     } else if(!constraints[i].getAllRoles()) {       String [] roles = constraints[i].findAuthRoles();       if(roles == null || roles.length == 0) {         authRequired = false;       }     }   }   // 3. 驗證用戶名和密碼   if(authRequired) {     // authenticate 是一個抽象方法,由不同的驗證方法實現     if (!authenticate(request, response, config)) {       return;     }    }   // 4. 驗證用戶是否包含授權的角色   if (!realm.hasResourcePermission(request, response,constraints,this.context)) {     return;   }   // 5. 已滿足任何和所有指定的約束   getNext().invoke(request, response); }

另外,AuthenticatorBase 還有一個比較重要的 register() 方法,它會把認證后生成的 Principal 對象設置到當前  Session 中,如果配置了SingleSignOn 單點登錄的閥門,同時把用戶身份、權限信息關聯到 SSO 中。

4. 單點登錄

Tomcat 支持通過一次驗證就能訪問部署在同一個虛擬主機上的所有 Web 應用,可通過以下配置實現:

<Host name="localhost" ...>   ...   <Valve className="org.apache.catalina.authenticator.SingleSignOn"/>   ... </Host>

Tomcat 的單點登錄是利用 Cookie 實現的:

當任一 Web 應用身份驗證成功后,都會把用戶身份信息緩存到 SSO 中,并生成一個名為 JSESSIONIDSSO 的 Cookie

當用戶再次訪問這個主機時,會通過 Cookie 拿出存儲的用戶 token,獲取用戶 Principal 并關聯到 Request 對象中

在單機環境下,沒有問題,在集群環境下,Tomcat 支持 Session 的復制,那單點登錄相關的信息也會同步復制嗎?后續會繼續分析 Tomcat  集群的原理和實現。

5. 小結

本文介紹的是 Tomcat 內部實現的登錄認證和權限,而應用程序通常都是通過 Filter 或者自定義的攔截器(如 Spring 的  Interceptor)實現登錄,或者使用第三方安全框架,比如 Shiro,但是原理都差不多。

到此,相信大家對“Tomcat容器的安全認證和鑒權講解”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石门县| 龙南县| 凌海市| 赤水市| 昌图县| 蒙城县| 科技| 乐都县| 湘潭县| 瑞昌市| 徐水县| 清镇市| 原平市| 吉首市| 本溪| 扶沟县| 民丰县| 抚松县| 石门县| 松潘县| 高邑县| 凉城县| 泰兴市| 济阳县| 罗定市| 彝良县| 荔波县| 庄浪县| 留坝县| 新津县| 苍梧县| 桐城市| 黄浦区| 前郭尔| 海口市| 方正县| 额敏县| 沅江市| 迁西县| 南丹县| 黔东|