中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

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

本篇內(nèi)容主要講解“Tomcat容器的安全認(rèn)證和鑒權(quán)講解”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Tomcat容器的安全認(rèn)證和鑒權(quán)講解”吧!

本篇內(nèi)容主要講解“Tomcat容器的安全認(rèn)證和鑒權(quán)講解”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Tomcat容器的安全認(rèn)證和鑒權(quán)講解”吧!

成都網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專(zhuān)注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、微信小程序、集團(tuán)成都定制網(wǎng)站等服務(wù)項(xiàng)目。核心團(tuán)隊(duì)均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗(yàn),服務(wù)眾多知名企業(yè)客戶(hù);涵蓋的客戶(hù)類(lèi)型包括:成都木包裝箱等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗(yàn),同時(shí)也獲得了客戶(hù)的一致好評(píng)!

1. 授權(quán)

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

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

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

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

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

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

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

Realm -  譯為域,域有泛指某種范圍的意思,在這個(gè)范圍內(nèi)存儲(chǔ)著用戶(hù)名、密碼、角色和權(quán)限,并且提供身份和權(quán)限驗(yàn)證的功能,典型的這個(gè)范圍可以是某個(gè)配置文件或數(shù)據(jù)庫(kù)

CombinedRealm - 內(nèi)部包含一個(gè)或多個(gè) Realm,按配置順序執(zhí)行身份驗(yàn)證,任一 Realm 驗(yàn)證成功,則表示成功驗(yàn)證

LockOutRealm - 提供用戶(hù)鎖定機(jī)制,防止在一定時(shí)間段有過(guò)多身份驗(yàn)證失敗的嘗試

Authenticator - 不同身份驗(yàn)證方法的接口,主要有 BASIC、DIGEST、FORM、SSL 這幾種標(biāo)準(zhǔn)實(shí)現(xiàn)

Principal - 對(duì)認(rèn)證主體的抽象,它包含用戶(hù)身份和權(quán)限信息

SingleSignOn - 用于支持容器內(nèi)多應(yīng)用的單點(diǎn)登錄功能

2.1 初始化

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

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

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

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

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

整個(gè)過(guò)程的核心代碼就在 AuthenticatorBase 的 invoke 方法中:

public void invoke(Request request, Response response) throws IOException, ServletException {   LoginConfig config = this.context.getLoginConfig();   // 0. Session 對(duì)象中是否緩存著一個(gè)已經(jīng)進(jìn)行身份驗(yàn)證的 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);         }       }     }   }   // 對(duì)于基于表單登錄,可能位于安全域之外的特殊情況進(jìn)行處理   String contextPath = this.context.getPath();   String requestURI = request.getDecodedRequestURI();   if (requestURI.startsWith(contextPath) && requestURI.endsWith(Constants.FORM_ACTION)) {           return;       }   }   // 獲取安全域?qū)ο螅J(rèn)配置是 LockOutRealm   Realm realm = this.context.getRealm();   // 根據(jù)請(qǐng)求 URI 嘗試獲取配置的安全約束   SecurityConstraint [] constraints = realm.findSecurityConstraints(request, this.context);     if ((constraints == null) /* && (!Constants.FORM_METHOD.equals(config.getAuthMethod())) */ ) {     // 為 null 表示訪(fǎng)問(wèn)的資源沒(méi)有安全約束,直接訪(fǎng)問(wèn)下一個(gè)閥門(mén)     getNext().invoke(request, response);     return;   }   // 確保受約束的資源不會(huì)被 Web 代理或?yàn)g覽器緩存,因?yàn)榫彺婵赡軙?huì)造成安全漏洞   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. 檢查用戶(hù)數(shù)據(jù)的傳輸安全約束   if (!realm.hasUserDataPermission(request, response, constraints)) {     // 驗(yàn)證失敗     // Authenticator已經(jīng)設(shè)置了適當(dāng)?shù)腍TTP狀態(tài)代碼,因此我們不必做任何特殊的事情     return;   }   // 2. 檢查是否包含授權(quán)約束,也就是角色驗(yàn)證   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. 驗(yàn)證用戶(hù)名和密碼   if(authRequired) {     // authenticate 是一個(gè)抽象方法,由不同的驗(yàn)證方法實(shí)現(xiàn)     if (!authenticate(request, response, config)) {       return;     }    }   // 4. 驗(yàn)證用戶(hù)是否包含授權(quán)的角色   if (!realm.hasResourcePermission(request, response,constraints,this.context)) {     return;   }   // 5. 已滿(mǎn)足任何和所有指定的約束   getNext().invoke(request, response); }

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

4. 單點(diǎn)登錄

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

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

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

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

當(dāng)用戶(hù)再次訪(fǎng)問(wèn)這個(gè)主機(jī)時(shí),會(huì)通過(guò) Cookie 拿出存儲(chǔ)的用戶(hù) token,獲取用戶(hù) Principal 并關(guān)聯(lián)到 Request 對(duì)象中

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

5. 小結(jié)

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

標(biāo)題名稱(chēng):Tomcat容器的安全認(rèn)證和鑒權(quán)講解
轉(zhuǎn)載注明:http://www.rwnh.cn/article30/sigcpo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷(xiāo)品牌網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷(xiāo)推廣、用戶(hù)體驗(yàn)定制網(wǎng)站、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
万全县| 东丽区| 廊坊市| 鸡东县| 儋州市| 昌乐县| 利川市| 宁明县| 北碚区| 尉氏县| 克山县| 衡阳县| 阿拉善左旗| 乐昌市| 丹寨县| 双桥区| 个旧市| 海盐县| 永宁县| 临高县| 柳州市| 壶关县| 中方县| 海南省| 嘉善县| 治多县| 白朗县| 阜阳市| 南岸区| 连城县| 新沂市| 东阿县| 阜康市| 连平县| 河津市| 团风县| 霍林郭勒市| 广州市| 克拉玛依市| 渝中区| 娄烦县|