成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Tomcat 容器的安全認(rèn)證和鑒權(quán)

運維 服務(wù)器運維
容器和 Web 應(yīng)用采用的是基于角色的權(quán)限訪問控制方式,其中容器需要實現(xiàn)認(rèn)證和鑒權(quán)的功能,而 Web 應(yīng)用則要實現(xiàn)授權(quán)的功能。

 大量的 Web 應(yīng)用都有安全相關(guān)的需求,正因如此,Servlet 規(guī)范建議容器要有滿足這些需求的機(jī)制和基礎(chǔ)設(shè)施,所以容器要對以下安全特性予以支持:

  • 身份驗證:驗證授權(quán)用戶的用戶名和密碼
  • 資源訪問控制:限制某些資源只允許部分用戶訪問
  • 數(shù)據(jù)完整性:能夠證明數(shù)據(jù)在傳輸過程中未被第三方修改
  • 機(jī)密性或數(shù)據(jù)隱私:傳輸加密(SSL),確保信息只能被信任用戶訪問

本文就以上問題,對 Tomcat 容器提供的認(rèn)證和鑒權(quán)的設(shè)計與實現(xiàn),以及內(nèi)部單點登錄的原理進(jìn)行分析。首發(fā)于微信公眾號頓悟源碼。

1. 授權(quán)

容器和 Web 應(yīng)用采用的是基于角色的權(quán)限訪問控制方式,其中容器需要實現(xiàn)認(rèn)證和鑒權(quán)的功能,而 Web 應(yīng)用則要實現(xiàn)授權(quán)的功能。

[[265756]]

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

  1. <security-constraint> <!-- 安全約束 --> 
  2.   <web-resource-collection> <!-- 限制訪問的資源集合 --> 
  3.     <web-resource-name>HTML Manager commands</web-resource-name
  4.     <url-pattern>/html/*</url-pattern> 
  5.   </web-resource-collection> 
  6.   <auth-constraint><!-- 授權(quán)可訪問此資源集合的角色 --> 
  7.      <role-name>manager-gui</role-name
  8.   </auth-constraint
  9. </security-constraint
  10.  
  11. <login-config><!-- 配置驗證方法 --> 
  12.   <auth-method>BASIC</auth-method> 
  13.   <realm-name>Tomcat Manager Application</realm-name
  14. </login-config> 
  15.  
  16. <security-role><!-- 定義一個安全角色 --> 
  17.   <description> 
  18.     The role that is required to access the HTML Manager pages 
  19.   </description> 
  20.   <role-name>manager-gui</role-name
  21. </security-role> 

這些安全相關(guān)的配置,都會在應(yīng)用部署時,初始化和設(shè)置到 StandardContext 對象中。更多詳細(xì)的內(nèi)容可查看規(guī)范對部署描述文件的解釋,接下來看 Tomcat 怎么設(shè)計和實現(xiàn)認(rèn)證及鑒權(quán)。

2. 認(rèn)證和鑒權(quán)的設(shè)計

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

 

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

  • Realm - 譯為域,域有泛指某種范圍的意思,在這個范圍內(nèi)存儲著用戶名、密碼、角色和權(quán)限,并且提供身份和權(quán)限驗證的功能,典型的這個范圍可以是某個配置文件或數(shù)據(jù)庫
  • CombinedRealm - 內(nèi)部包含一個或多個 Realm,按配置順序執(zhí)行身份驗證,任一 Realm 驗證成功,則表示成功驗證
  • LockOutRealm - 提供用戶鎖定機(jī)制,防止在一定時間段有過多身份驗證失敗的嘗試
  • Authenticator - 不同身份驗證方法的接口,主要有 BASIC、DIGEST、FORM、SSL 這幾種標(biāo)準(zhǔn)實現(xiàn)
  • Principal - 對認(rèn)證主體的抽象,它包含用戶身份和權(quán)限信息
  • SingleSignOn - 用于支持容器內(nèi)多應(yīng)用的單點登錄功能

2.1 初始化

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

web.xml 中聲明的安全約束會初始化成對應(yīng)的 SecurityConstraint、SecurityCollection 和 LoginConfig 對象,并關(guān)聯(lián)到一個 StandardContext 對象。

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

3. 一次請求認(rèn)證和鑒權(quán)過程

Context 在 Tomcat 內(nèi)部就代表著一個 Web 應(yīng)用,假設(shè)配置使用 BASIC 驗證方法,那么 Context 內(nèi)部的 Pipeline 就有 BasicAuthenticator 和 StandardContextValve 兩個閥門,當(dāng)請求進(jìn)入 Context 管道時,就首先進(jìn)行認(rèn)證和鑒權(quán),方法調(diào)用如下:

 

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

  1. public void invoke(Request request, Response response) throws IOException, ServletException { 
  2.   LoginConfig config = this.context.getLoginConfig(); 
  3.   // 0. Session 對象中是否緩存著一個已經(jīng)進(jìn)行身份驗證的 Principal 
  4.   if (cache) { 
  5.     Principal principal = request.getUserPrincipal(); 
  6.     if (principal == null) { 
  7.       Session session = request.getSessionInternal(false); 
  8.       if (session != null) { 
  9.         principal = session.getPrincipal(); 
  10.         if (principal != null) { 
  11.           request.setAuthType(session.getAuthType()); 
  12.           request.setUserPrincipal(principal); 
  13.         } 
  14.       } 
  15.     } 
  16.   } 
  17.   // 對于基于表單登錄,可能位于安全域之外的特殊情況進(jìn)行處理 
  18.   String contextPath = this.context.getPath(); 
  19.   String requestURI = request.getDecodedRequestURI(); 
  20.   if (requestURI.startsWith(contextPath) && requestURI.endsWith(Constants.FORM_ACTION)) { 
  21.           return
  22.       } 
  23.   } 
  24.   // 獲取安全域?qū)ο螅J(rèn)配置是 LockOutRealm 
  25.   Realm realm = this.context.getRealm(); 
  26.   // 根據(jù)請求 URI 嘗試獲取配置的安全約束 
  27.   SecurityConstraint [] constraints = realm.findSecurityConstraints(request, this.context); 
  28.   
  29.   if ((constraints == null) /* && (!Constants.FORM_METHOD.equals(config.getAuthMethod())) */ ) { 
  30.     // 為 null 表示訪問的資源沒有安全約束,直接訪問下一個閥門 
  31.     getNext().invoke(request, response); 
  32.     return
  33.   } 
  34.   // 確保受約束的資源不會被 Web 代理或瀏覽器緩存,因為緩存可能會造成安全漏洞 
  35.   if (disableProxyCaching &&  
  36.       !"POST".equalsIgnoreCase(request.getMethod())) { 
  37.       if (securePagesWithPragma) { 
  38.           response.setHeader("Pragma""No-cache"); 
  39.           response.setHeader("Cache-Control""no-cache"); 
  40.       } else { 
  41.           response.setHeader("Cache-Control""private"); 
  42.       } 
  43.       response.setHeader("Expires", DATE_ONE); 
  44.   } 
  45.   int i; 
  46.   // 1. 檢查用戶數(shù)據(jù)的傳輸安全約束 
  47.   if (!realm.hasUserDataPermission(request, response, constraints)) { 
  48.     // 驗證失敗 
  49.     // Authenticator已經(jīng)設(shè)置了適當(dāng)?shù)腍TTP狀態(tài)代碼,因此我們不必做任何特殊的事情 
  50.     return
  51.   } 
  52.   // 2. 檢查是否包含授權(quán)約束,也就是角色驗證 
  53.   boolean authRequired = true
  54.   for(i=0; i < constraints.length && authRequired; i++) { 
  55.     if(!constraints[i].getAuthConstraint()) { 
  56.       authRequired = false
  57.     } else if(!constraints[i].getAllRoles()) { 
  58.       String [] roles = constraints[i].findAuthRoles(); 
  59.       if(roles == null || roles.length == 0) { 
  60.         authRequired = false
  61.       } 
  62.     } 
  63.   } 
  64.   // 3. 驗證用戶名和密碼 
  65.   if(authRequired) { 
  66.     // authenticate 是一個抽象方法,由不同的驗證方法實現(xiàn) 
  67.     if (!authenticate(request, response, config)) { 
  68.       return
  69.     }  
  70.   } 
  71.   // 4. 驗證用戶是否包含授權(quán)的角色 
  72.   if (!realm.hasResourcePermission(request, response,constraints,this.context)) { 
  73.     return
  74.   } 
  75.   // 5. 已滿足任何和所有指定的約束 
  76.   getNext().invoke(request, response); 

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

4. 單點登錄

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

  1. <Host name="localhost" ...> 
  2.   ... 
  3.   <Valve className="org.apache.catalina.authenticator.SingleSignOn"/> 
  4.   ... 
  5. </Host> 

Tomcat 的單點登錄是利用 Cookie 實現(xiàn)的:

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

當(dāng)用戶再次訪問這個主機(jī)時,會通過 Cookie 拿出存儲的用戶 token,獲取用戶 Principal 并關(guān)聯(lián)到 Request 對象中

在單機(jī)環(huán)境下,沒有問題,在集群環(huán)境下,Tomcat 支持 Session 的復(fù)制,那單點登錄相關(guān)的信息也會同步復(fù)制嗎?后續(xù)會繼續(xù)分析 Tomcat 集群的原理和實現(xiàn)。

5. 小結(jié)

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

至此,除了集群的實現(xiàn),Tomcat 的核心原理已經(jīng)分析完畢,接下來將會模擬實現(xiàn)一個簡單的 Tomcat,歡迎關(guān)注。

責(zé)任編輯:武曉燕 來源: 頓悟源碼
相關(guān)推薦

2024-05-28 08:24:18

2024-01-26 14:35:03

鑒權(quán)K8sNode

2014-07-10 11:34:05

2021-09-02 07:00:32

鑒權(quán)Web 應(yīng)用Cookie-sess

2018-01-10 14:22:05

2024-10-14 11:56:50

2022-12-02 16:28:47

2022-05-31 08:36:41

微服務(wù)網(wǎng)關(guān)鑒權(quán)

2024-10-10 12:21:56

JWTSession擴(kuò)展性

2023-04-17 08:56:29

微服務(wù)鑒權(quán)業(yè)務(wù)

2021-10-26 11:42:51

系統(tǒng)

2024-01-08 18:48:21

2023-03-30 07:48:46

接口鑒權(quán)SpringBoot

2023-10-31 07:13:43

2020-03-19 10:13:13

OkHttpWebSocket

2021-03-03 13:25:35

CookieSessionToken

2014-02-14 13:21:22

2021-10-27 09:32:48

Casbin鑒權(quán)權(quán)限

2025-02-26 13:00:00

SpringBootJava開發(fā)

2020-06-16 07:00:00

容器Kebernetes容器安全
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久精品视频在线播放 | 欧美福利网站 | 欧美日韩国产三级 | heyzo在线| 精品一二三区 | 一区二区三区回区在观看免费视频 | 国产99久久精品一区二区永久免费 | 久久亚洲一区二区三区四区 | 成av人电影在线 | 亚洲美女一区二区三区 | h视频免费观看 | 国产激情视频在线免费观看 | 久久精品久久综合 | 一级国产精品一级国产精品片 | 国产三级| 成人精品 | 在线观看亚洲欧美 | 国产高清av免费观看 | 一区二区三区国产 | 一区二区在线 | 日本精品一区二区三区在线观看视频 | 欧美日韩在线精品 | 91天堂网| 欧美一区二区三区高清视频 | 福利片在线观看 | 国产精品视频免费观看 | 亚洲福利网 | 免费看黄视频网站 | 欧美日韩黄 | va在线 | 日韩精品一区二区三区中文字幕 | 亚洲情侣视频 | 国产性网 | 日韩 欧美 综合 | 精产国产伦理一二三区 | 欧美精品成人一区二区三区四区 | 欧洲视频一区二区 | 精品国产免费一区二区三区五区 | 黄色片视频免费 | 7777在线视频 | 亚洲一区二区三区四区视频 |