jsp 安全

 

 

 

一.  身份驗證和受權

  認證是檢驗某人真正是他/她自稱的那我的的過 程。在一個Servlet/JSP應用程序中,身份驗證通常經過 檢查用戶名密碼是否正確。受權是檢查該級別的用戶是 否具有訪問權限。它適用於包括多個區域的應用程序, 其中用戶能夠利用這個應用程序的部分模塊,可是其餘 模塊就沒有權限。例如,一個在線商店可被劃分紅的一 般部分(用於通常公衆瀏覽和搜索產品)、買家部分 (註冊用戶下訂單)和後臺管理部分(適用於管理 員)。這三者中,後臺管理部分須要訪問的最高權限。 管理員用戶不只須要進行身份認證,他們還須要得到後 臺管理部分的權限。html

   訪問級別一般被稱爲角色。在部署一個Servlet/JSP 應用程序時能夠方便地經過模塊分類和配置,使得每一個 模塊只有特定角色才能訪問。這是經過在部署中聲明安 全約束描述符完成的。換句話說,就是聲明式安全。在 這個範圍的另外一端,內容限制是經過編程實現檢驗用戶 名和密碼與數據庫中存儲的用戶名和密碼對是否匹配。java

  大多數Servlet和JSP應用程序的身份驗證和受權首 先要驗證用戶名和密碼與數據庫表是否一致。一旦驗證 成功,可檢查另外一個受權在同一個表中存儲的用戶名和 密碼的表或字段。使用聲明式安全可以讓您的編程更簡 潔,由於Servlet/JSP容器負責身份驗證和受權過程。此 外,Servlet/JSP容器配置數據庫來驗證你已經在應用程 序中使用。最重要的是,使用聲明式身份驗證的用戶名 和密碼可在被髮送到服務器以前由瀏覽器對其加密後再 發送給服務器。聲明式安全的缺點是,支持數據加密的 身份驗證方法只能使用一個默認登陸對話框,不能對界 面和操做進行個性化定製。這個緣由就足以讓人放棄聲 明式安全。聲明性安全的惟一方法是容許使用一個自定 義的HTML表單,不幸的是數據傳輸不加密。web

   Web應用程序的某些部分,如管理模塊,是不面向 客戶的,因此登陸表單的外觀是沒有關聯的。在這種情 況下,聲明式安全仍然被使用。正則表達式

   聲明式安全有趣的部分固然就是安全約束不編入 Servlet了。相反,它們在應用程序部署時聲明在部署描 述符中。所以,它具備至關大的靈活性來肯定用戶和角 色對訪問的應用程序或部分模塊的權限。算法

  要使用聲明式安全,首先定義用戶和角色。根據您 所使用的容器,您能夠將用戶和角色信息存儲在一個文 件或數據庫表中,而後,您對應用程序中的資源或集合 施加約束。數據庫

   如今,您如何不經過編程來驗證用戶?你會發現後 面的答案在於HTTP而不是Servlet規範。編程

二. 指定用戶和角色

  每個兼容Servlet/JSP容器必須提供一個定義用戶 和角色的方法。若是你使用Tomcat,能夠經過編輯conf 目錄中的Tomcat-user.xml來建立用戶和角色。tomcat-users.xml數組

tomcat-users.xml 文件瀏覽器

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="manager"/>
<role rolename="member"/>
<user username="tom" password="secret" roles="manager,memb
er"/>
<user username="jerry" password="secret" roles="member"/>
</tomcat-users>

  tomcat-users.xml文件是一個xml文檔的根元素 tomcat-user。在裏面是role和user元素。role元素定義角 色,user元素定義用戶。role元素有rolename屬性指定角 色名。user元素具備username、password和role屬性。 sername屬性指定用戶名,password屬性指定密碼,role 屬性指定角色或用戶屬於的角色。tomcat

  tomcat-users.xml文件聲明瞭兩個角色 (經理和成員)和兩個用戶(tom和jerry)。用戶tom是 一個成員和經理的角色,而傑瑞只屬於成員角色。很明 顯,湯姆比傑瑞具備接入更多應用的權限。

  Tomcat還支持經過數據庫表來匹配角色和用戶。 你能夠配置Tomcat使用JDBC來驗證用戶身份。

二. 實施安全約束

  你已經學會經過把靜態資源和JSP頁面放在WEBINF目錄下來隱藏起來。資源放置在這裏不能直接經過 輸入URL訪問,但仍然能夠從一個Servlet或JSP頁面進 入。雖然這種方法簡單明瞭,缺點是資源隱藏在這裏永 遠是隱藏的,沒有辦法直接訪問。若是你只是簡單地想 保護資源不被未經受權的用戶訪問,你能夠把它們放在 應用程序目錄下的一個目錄中,在部署描述符中聲明一 個安全約束。

  security-constraint元素指定一個資源集合和角色或 角色能夠訪問的資源。這個元素有兩個子元素:webresource-collection和auth-constraint。

  web-resource-collection元素指定一組資源,能夠包 括web-resource-name、description、url-pattern、httpmethod和http-method-ommission等子元素。

  web-resource-collection元素能夠有多個url模式子元 素,每個都是指一個URL正則表達式用於指定安全約 束。您可使用星號的url模式元素來引用一個特定資 源類型(例如, * . jsp)或全部資源目錄(好比/ *或/ jsp / *)。然而,你不能同時指定兩個,例如,在一個 特定的目錄中指定一個特定類型。所以,下面的URL表 達式指定jsp目錄下的全部JSP頁面是無效的:/ JSP / * . JSP。相反,使用/ jsp / * ,也將限制任何在jsp目錄下的 非JSP頁面。

  http-method元素爲封閉的安全約束的應用命名了一 個http方法。例如,一個web-resource- collection元素以 GET http-method命名,代表該web-resource-collection元 素僅適用於HTTP GET方法。包含資源集合的安全約束 不能防止其餘HTTP方法,如PUT方法。沒有httpmethod元素表示安全約束限制了全部HTTP訪問方法。 你能夠在同一個web-resource-collection中擁有多個 httpmethod元素。

  http-method-omission元素指定一個不包含HTTP方 法的安全約束。所以,指定< http-methodomission > GET< / http-method-omission >表示限制除了GET外的所 有HTTP方法。

  http-method元素和http-method-omission元素不能出 如今相同的web-resource-collection元素裏。

  在部署描述符中能夠有多個security-constraint元 素。若是security-constraint元素沒有auth-constraint元 素,那麼這個資源集合是不被保護的。此外,若是你指 定的角色沒有在容器中定義,那麼沒有人可以直接訪問 這個資源集合。然而,你仍然能夠經過一個servlet或 JSP頁面轉向集合中的資源。

  這裏有個例子,下面的xml文件的securityconstraint元素限制全部JSP頁面的訪問權限。因爲authconstraint不包含rolename元素,所以沒法經過它們的 urls直接訪問這個資源

  防止訪問特定目錄下的資源

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
➥ http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
>
<!-- restricts access to JSP pages -->
<security-constraint>
<web-resource-collection>
<web-resource-name>JSP pages</web-resource-name>
<url-pattern>*.jsp</url-pattern>
</web-resource-collection>
<!-- must have auth-constraint, otherwise the
specified web resources will not be restricted -->
<auth-constraint/>
</security-constraint>
</web-app>

 

  servlet容器將發送一個HTTP 403錯誤:訪問所請求 的資源已經被否定。

  如今讓咱們看看如何對用戶進行身份驗證和受權。

二.身份驗證方法

  如今你應該知道如何實施資源集合的安全約束,你 也應該學會如何驗證訪問資源的用戶信息。因爲以聲明 的方式得到的資源,在部署描述符中使用的是安全約束 元素,所以身份驗證可使用HTTP 1.1提供的解決方 案:基本訪問認證和摘要訪問身份驗證。此外,還能夠 使用基於表單的訪問認證。HTTP身份驗證是在RFC 2617中定義的。你能夠在這裏下載規範:

http://www.ietf.org/rfc/rfc2617.txt

  基本訪問身份驗證,或簡稱基本認證,是一個接受 用戶名和密碼的HTTP身份驗證。訪問受保護的資源的 用戶將被服務器拒絕,服務器會返回一個401(未經授 權)響應。該響應包含一個WWW-Authenticate頭,包 含至少一個適用於所請求資源的認證域。這裏有一個響 應內容的例子:

  

HTTP/1.1 401 Authorization Required
Server: Apache-Coyote/1.1
Date: Wed, 21 Dec 2011 11:32:09 GMT
WWW-Authenticate: Basic realm="Members Only

  瀏覽器會顯示用戶輸入用戶名和密碼的登陸對話 框。當用戶單擊「登陸」按鈕時,用戶名將被加上一個冒 號並與密碼鏈接起來造成一個字符串。該字符串在被髮 送到服務器以前將用Base64算法編碼。成功登陸後,服 務器將發送所請求的資源。Base64是一個很是弱的算 法,所以很容易解密Base64的信息。考慮使用摘要訪問 認證來替代。

  app12b應用程序展現瞭如何使用基本訪問認證。下面提供了應用程序的部署描述符。第一個securityconstraint元素保護直接訪問的JSP頁面。第二個限制訪 問Servlet1 servlet的經理和成員角色。Servlet1類是一個 簡單的進入到1.jsp的servlet,以下所示。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
➥ http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <!-- restricts access to JSP pages -->
    <!--  啓用安全訪問 -->
    <security-constraint>
    <!--  設置被保護的資源名 以及路徑 -->
        <web-resource-collection>
            <web-resource-name>JSP pages</web-resource-name>
            <url-pattern>*.jsp</url-pattern>
        </web-resource-collection>
        <!-- must have auth-constraint, otherwise the specified web resources will 
            not be restricted -->
            <!--  保護規則 若是沒有auth-constarint 將不會保護資源,  若是沒有auth 
            設置用角色和用戶名,則全部人都不得訪問-->
        <auth-constraint />
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Servlet1</web-resource-name>
            <url-pattern>/servlet1</url-pattern>
        </web-resource-collection>
        <auth-constraint>
        <!--   -->
            <role-name>tomcat</role-name>
            <role-name>tom</role-name>
        </auth-constraint>
    </security-constraint>
    <!--  訪問方式設置  -->
    <login-config>
    <!--  設置訪問的方法爲基本訪問權限  -->
        <auth-method>BASIC</auth-method>
        <!--   -->
        <realm-name>Members Only</realm-name>
    </login-config>
</web-app>

  在清單12.3中的部署描述符中最重要的元素是 loginconfig元素。它有兩個子元素:auth-method和 realm-name。要使用Basic access authentication,您必須 將它的值設爲BASIC(全部字母大寫)。在瀏覽器登陸 對話框中顯示的realm-name元素必須賦值。

tomcat 的tomcat-users.xml

<!--
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
  <user username="role1" password="<must-be-changed>" roles="role1"/>
-->
<role rolename="tomcat" />
<user username="tom" password="1" roles="tomcat"    />

</tomcat-users>

 此時,沒法像以前那樣直接看到Servlet1的輸出, 相反,你會收到一個提示——要求輸入用戶名和密碼

  只要auth-constraint元素映射到Servlet1指定經理和 成員的角色,您可使用tom或者jerry登陸。 摘要訪問接入認證,或簡稱摘要認證,也是一個 HTTP認證,相似基本認證。但不使用弱加密的base64 算法,而使用MD5算法建立一個組合用戶名、域名和 密碼的哈希值,併發送到服務器。摘要訪問身份驗證是 爲了取代基本的訪問認證,由於它提供了更安全的環 境。

  servlet和JSP容器沒有義務支持摘要訪問認證但大 多數都有作。

  配置應用程序使用摘要訪問認證的方式相似於使用 基本訪問認證。事實上,惟一的區別是login-config元素 內的auth-method元素的值。對於摘要訪問認證,authmethod元素值必須是DIGEST(大寫)。

  做爲一個例子,該app12c演示應用的Digest access authentication(摘要訪問認證)的使用

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
➥ http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <!-- restricts access to JSP pages -->
    <!--  啓用安全訪問 -->
    <security-constraint>
    <!--  設置被保護的資源名 以及路徑 -->
        <web-resource-collection>
            <web-resource-name>JSP pages</web-resource-name>
            <url-pattern>*.jsp</url-pattern>
        </web-resource-collection>
        <!-- must have auth-constraint, otherwise the specified web resources will 
            not be restricted -->
            <!--  保護規則 若是沒有auth-constarint 將不會保護資源,  若是沒有auth 
            設置用角色和用戶名,則全部人都不得訪問-->
        <auth-constraint />
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Servlet1</web-resource-name>
            <url-pattern>/servlet1</url-pattern>
        </web-resource-collection>
        <auth-constraint>
        <!--   -->
            <role-name>tomcat</role-name>
            <role-name>tom</role-name>
        </auth-constraint>
    </security-constraint>
    <!--  訪問方式設置  -->
    <login-config>
    <!--  設置限制訪問的規則  -->
        <auth-method>DIGEST</auth-method>
        <!--   -->
        <realm-name>>Digest1 authentication</realm-name>
    </login-config>
</web-app>

  咱們在瀏覽器裏輸入這個地址來測試一下:

1. 基於表單的認證

  基本和摘要訪問認證不容許你使用一個定製的登陸 表單。若是你必須有一個自定義窗體,那麼你可使用 基於表單的認證。因爲發送明文,你應當與SSL配合使 用。

  基於表單的身份驗證,您須要建立一個登陸頁面和 一個錯誤的頁面,這能夠是HTML或JSP頁面。第一次 請求受保護的資源,servlet和JSP容器將登陸頁面。在 成功登陸時,所請求的資源將被髮送。若是登陸失敗, 用戶會看到錯誤頁.

  使用form-based authentication(基於表單的身份驗 證),您的部署描述符的auth-method 元素的值必須是 FORM(大寫)。此外,login-config元素必須有formlogin-config元素節點,該節點有兩個子元素,formlogin-page和form-error-page。以下是一個基於表單的身 份驗證登陸 login-config元素的示例:

<!-- 訪問方式設置 -->
    <login-config>
    <!--   設置登錄驗證的方法爲來來自form表單  -->
        <auth-method>FORM</auth-method>
        <form-login-config>
           <!--   甚至登錄頁面  -->
            <form-login-page>/login.html</form-login-page>
            <!--  設置錯誤頁面 -->
            <form-error-page>/error.html</form-error-page>
        </form-login-config>
    </login-config>

app12d的部署描述符,基於表單身份驗證 的例子

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
➥ http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <!-- restricts access to JSP pages -->
    <!-- 啓用安全訪問 -->
    <security-constraint>
        <!-- 設置被保護的資源名 以及路徑 -->
        <web-resource-collection>
            <web-resource-name>JSP pages</web-resource-name>
            <url-pattern>*.jsp</url-pattern>
        </web-resource-collection>
        <!-- must have auth-constraint, otherwise the specified web resources will 
            not be restricted -->
        <!-- 保護規則 若是沒有auth-constarint 將不會保護資源, 若是沒有auth 設置用角色和用戶名,則全部人都不得訪問 -->
        <auth-constraint />
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Servlet1</web-resource-name>
            <url-pattern>/servlet1</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <!-- -->
            <role-name>tomcat</role-name>
            <role-name>tom</role-name>
        </auth-constraint>
    </security-constraint>
    <!-- 訪問方式設置 -->
    
    <login-config>
    <!--   設置登錄驗證的方法爲來來自form表單  -->
        <auth-method>FORM</auth-method>
        <form-login-config>
           <!--   甚至登錄頁面  -->
            <form-login-page>/login.html</form-login-page>
            <!--  設置錯誤頁面 -->
            <form-error-page>/error.html</form-error-page>
        </form-login-config>
    </login-config>

</web-app>

login.html頁面

<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login Form</h1>
<form action='j_security_check' method='post'>
<div>
User Name: <input name='j_username'/>
</div>
<div>
Password: <input type='password' name='j_password'/>
</div>
<div>
<input type='submit' value='Login'/>
</div>
</form>
</body>
</html>

error.html頁面

<!DOCTYPE html>
<html>
<head>
<title>Login error</title>
</head>
<body>
Login failed.
</body>
</html>

測序下app12d基於表單的認證,直接瀏覽器這個 URL。

2.客戶端證書認證

  也稱爲client-cert認證,客戶端證書身份經過 HTTPS(HTTP經過SSL)認證,要求每一個客戶有一個 客戶端證書。這是一個很是強大的身份驗證機制,但不 適合在互聯網上部署的應用程序,由於它是不切實際的 要求每一個用戶本身的數字證書。然而,這種身份驗證方 法能夠用來訪問組織內部的應用。

 三. 安全套接層

1. 密碼學

  咱們時不時須要一個安全信息通道,使得信息是安 全的,即使外部能夠訪問信息,也不能理解並篡改信 息。

  從歷史上看,密碼只關心加密和解密,在雙方能夠 放心的交換信息,只有他們能夠讀取消息。在開始的時 候,人們使用對稱密碼加密和解密消息。在對稱密碼, 您使用相同的密鑰來加密和解密消息。這是一個很是簡 單的加密/解密技術。

  假設,加密方法使用一個祕密號碼前移中每一個字符 的字母表。所以,若是密碼是2,加密 版「ThisFriday」是「vjkuhtkfca」。當你到了字母表的結 尾,你從頭開始,所以Y變成A.接收器,知道密鑰是 2,能夠很容易地解密消息。

  然而,對稱加密要求雙方提早知道用於加密/解密 的密鑰。對稱加密是不適合互聯網的緣由以下:

  • 兩人交換消息每每不知道對方。例如,在購買一本 書在亞馬遜網站上你須要發送您的我的資料和信用 卡信息。若是對稱密碼被使用,你必須調用亞馬遜 的交易以前必須贊成這個密鑰。
  • 每一個人都但願可以與其餘各方溝通。若是是使用對 稱密碼,每一個人都會有不一樣的獨特的鑰匙應對不一樣 的地方。
  • 既然你不知道你要與之通訊的實體,你須要肯定他 們的真實身份。
  • 信息在互聯網上經過許多不一樣的計算機傳播。這樣 很容易挖掘其餘人的消息。對稱密碼體制並不能保 證數據沒被第三方篡改。

  所以,今天的安全通訊在互聯網上使用非對稱加 密,提供了這三個特色:

  • 加密/解密。信息對第三方進行加密隱藏。只有預期 的接收者才能解密。
  • 身份驗證。驗證確保實體就是聲稱者。
  • 數據的完整性。許多計算機在互聯網上發送的消息 傳遞。它必須是確保發送的數據不變,無缺無損。

  在非對稱加密,使用公鑰加密。這種類型的加密, 加密和解密的數據是經過使用一對非對稱密鑰:公鑰和 私鑰。私鑰是私有的。頒發者必須保持它在一個安全的 地方,它不能落入任何另外一方的手裏。公鑰分發給公 衆,一般誰均可如下載這個密鑰與頒發者溝通。您能夠 使用工具來生成公鑰和私鑰。

  公鑰加密的優勢是:使用公共密鑰加密的數據只能 使用對應的私鑰進行解密,在一樣使用私鑰加密的數據 只能使用對應的公鑰解密。這優雅的算法是基於大素 數,由Ron Rivest,Adi Shamir,和Len Adleman在麻省 理工學院(MIT)在1977年發明的。它們簡稱爲RSA算 法,基於他們的姓氏的首字母。

  RSA算法是在互聯網上的使用實踐被證實,特別是 電子商務,由於只有供應商要求有一個密鑰對來同全部 的買家進行安全通訊。

  愛麗絲(Alice)與鮑伯(Bob)是普遍地代入密碼 學和物理學領域的通用角色。這裏我也會使用他們

2. 加密/解密

  交換信息的一方必須有一個密鑰對。若是愛麗絲想 和鮑勃交流,鮑勃有公共密鑰和私有密鑰。鮑勃將公鑰 送給愛麗絲,愛麗絲能夠用它來加密發送給Bob的消 息。只有鮑伯能夠解密由於他擁有對應私鑰。若鮑勃要 發消息給愛麗絲,鮑勃使用本身的私鑰加密消息,愛麗 絲能夠用Bob的公鑰解密。

  然而,要交出本身的公共密鑰,除非鮑勃能夠與愛 麗絲見面,這種方法並不完美。有一對密鑰的任何人都 能夠聲稱本身是鮑勃,可是愛麗絲卻沒法辨別。在互聯 網上,在雙方交換消息常常生活在半個地球以外,會面 每每是不可能的。

3. 認證

  SSL身份驗證是經過引入證書。證書包含如下幾 個:

  • 公鑰。
  • 關於主題的信息,即公開密鑰的全部者。
  • 證書發行機構的名字。
  • 到證書到期時間的時間戳

  關於證書,重要的是,它必須由一個可信的數字籤 名證書頒發者,如VeriSign或Thawte。對電子文件進行 數字簽名(一文件,一個JAR文件,等等)是你的文 檔/文件中添加你的簽名。原始文件沒有加密,和簽名 的真正目的是爲了保證文件/文件沒有被篡改。簽署一 份文件涉及建立一個文檔的摘要,並使用簽名者的私鑰 對摘要加密。要檢查文檔是否仍它仍是原來的狀態,你 執行這兩個步驟:

  (1)使用簽名者的公鑰解密伴隨文件摘要。你很 快就會發現,一個受信任的證書發行者的公鑰很容易獲 得。

  (2)建立一個文檔的摘要。

  (3)比較結果的步驟1和步驟2的結果。若是二者 匹配,那麼該文件未被篡改。

  這種認證方法由於只有私鑰的持有者能夠加密文件 摘要,這種摘要只能使用相應的公鑰解密。若是你相信 你持有原始公鑰,而後你知道文件是否已被改變。

注意:

  因爲證書能夠由受信任的證書頒發者進行數字簽名,人們公開發布證書,而不是公鑰。

  有一些證書發行機構,包括VeriSign和Thawte。證 書頒發者有一對公鑰和私鑰。要申請一個證書,鮑勃產 生一對密鑰,併發送本身的公鑰證書給頒發者,後者通 過叫鮑勃送他的護照複印件或其餘類型的身份證件進行 驗證。經覈實,證書頒發者使用其私鑰簽定證書。通 過「簽名」這意味着加密。所以,證書只能經過使用證書 發放者的公鑰讀取。證書頒發者的公鑰一般是分佈廣 泛。例如,IE瀏覽器,網景,FireFox和其餘瀏覽器默 認包括幾個證書頒發者的公鑰。

  例如,在IE中,單擊「工具-> Internet選項->內容-> 憑證->受信任的根證書頒發機構」選項卡查看證書列 表。。

上圖 證書發行者的公鑰是嵌入在IE瀏覽器

  如今,有一個證書,鮑勃將分發證書代替他的公鑰 在與另外一方交換信息以前。

  下面是它如何工做的:

  A->-B嗨鮑勃,我想和你說話,但首先我須要確認 你真的鮑勃。

  B->-A很公平,這裏是個人證件

  A->-B這是不夠的,我須要一些從你身上的別的東 西

  B->-A愛麗絲,這真是我+【使用Bob的私鑰信息摘 要加密】

  在鮑勃愛麗絲的最後一條消息,該消息已經使用其 私鑰加密,來講服愛麗絲的消息是真實的。這就是如何 進行認證證實。愛麗絲同鮑勃交流,鮑勃發給愛麗絲其 證書。然而,只有證書是不夠的,由於任何人均可以得 到Bob的證書。記得鮑勃給證書的人誰願意和他交換信 息。所以,鮑勃送她的消息(「愛麗絲,這真是我」), 並用本身的私鑰加密同一消息的摘要。

  愛麗絲從證書獲得Bob的公鑰。她能作到這一點, 由於證書是使用證書頒發者的私鑰簽名,愛麗絲已得到 了證書頒發者的公鑰(她的瀏覽器保持它的一個副 本)。如今,她還獲得了消息,並使用Bob的私鑰加密 的摘要。因此愛麗絲須要作的就是生成該消息的摘要, 並將其與鮑勃所發送的摘要進行比較。愛麗絲能夠解密 它,由於它已經使用Bob的私鑰加密,Alice有Bob的公 開密鑰的副本。若是二者匹配,愛麗絲能夠確定的是, 對方真的是鮑勃。

  愛麗絲驗證鮑勃後首先發送將用於隨後的消息交換 的密鑰。這是正確的,一旦安全通道的創建,SSL使用 對稱加密,由於它比非對稱加密快得多。

  如今,這個情景中還有一件事缺失。在互聯網上傳 遞的消息多臺計算機。你如何確保這些信息的完整性, 由於任何人均可以攔截在路上這些消息?

4. 數據的完整性

  Mallet,惡意的一方,能夠坐在愛麗絲和鮑勃之 間,試圖破譯發送的消息。不幸的是他,即便他能複製 的訊息,但信息是加密的,且Mallet不知道的密鑰。然 而,Mallet會破壞信息或不傳達一些他們。爲了克服這 個問題,SSL引進一個消息認證碼(MAC)。MAC是 用一個密鑰和傳輸的數據計算出的數據塊。由於Mallet 不知道祕鑰,他不能正確的計算摘要。消息接收器能夠 所以會發現是否有人企圖篡改數據或者數據不完整。如 果發生這種狀況,雙方可中止溝通。

  MD5是其中一個這樣的消息摘要算法。它是由 RSA發明,是很是安全的。舉例說明,若是使用128位 的MAC值,惡意的一方的猜想正確的價值的概率是 18446744073709551616分之1,或幾乎沒有。

5. SSL是怎麼工做的

  如今你知道SSL如何處理加密/解密,認證和數據完 整性的問題,讓咱們回顧一下SSL是如何工做的。這一 次,讓咱們Amazon.com(代替鮑勃)和買方(而不是 愛麗絲)爲例。Amazon.com,和任何其餘真正的電子 商務供應商同樣,他已向受信任的證書頒發者申請證 書。買方使用Internet Explorer,它嵌入了可信證書發行 機構的公鑰。買方並不真的須要知道如何SSL的工做原 理,也不須要有一個公共密鑰或私有密鑰。他須要保證 的一件事是,當進入重要的細節時,如信用卡號時,所 使用的協議是HTTPS來代替HTTP。這出如今url框裏。 所以,http://www.amazon.com,它必須以https開頭。例 如:https://secure.amazon.com。一些瀏覽器也顯示一個 安全的圖標在地址欄。

  顯示了IE安全標誌。

  當買家進入一個安全的網頁(當他已經完成購 物),這是他的瀏覽器和亞馬遜的服務器在後臺發生的 一系列事件。

  瀏覽器:你真的Amazon.com嗎?

  服務器:是的,這是個人證書。

  而後瀏覽器使用發行者證書的公鑰解密檢查證書的 有效性。若是有什麼是錯的,例如,若是證書過時了, 瀏覽器將警告用戶。若是用戶贊成繼續儘管證書過時, 瀏覽器將繼續下去。

  瀏覽器:單獨的證書是不夠的,請給一些別的東 西。

  服務器:我真的Amazon.com + [使用亞馬遜網站的 私鑰加密同一消息的摘要]。

  瀏覽器使用Amazon的公鑰解密摘要,並建立「我真 的Amazon.com」的摘要。若是二者匹配,驗證成功。那 麼瀏覽器就會產生一個隨機密鑰,使用Amazon的公鑰 加密。這個隨機密鑰來加密和解密隨後的消息。換句話 說,一旦亞馬遜使用加密認證,它將是對稱加密認證, 由於它比非對稱加密快不少。除了消息,雙方還將發送 消息摘要來確保信息的完整不變。

四. 編程式安全

  儘管聲明性安全簡單易懂,但在特殊狀況下,你想 寫代碼來確保你的應用程序。爲了這個目的,你能夠在 HttpServletRequest接口使用安全註釋類型和方法。都是 在這部分討論。

1. 安全註釋類型

  部署描述符中的 security-constraint元素集合用來限制訪問資源。此元素的 一個方面是您使用相匹配的資源的URL進行限制的URL 模式。Servlet 3提供的註釋類型能夠在一個servlet級別 執行相同的工做。使用這些註釋類型,你能夠限制訪問 一個servlet,而不用在部署描述符中添加securityconstraint元素。可是,你仍然須要一個login-config元素 的部署描述符來選擇一個身份驗證方法。  

  在javax.servlet.annotation包,安全相關的有三個注 釋類型。他們是ServletSecurity,HttpConstraint,和 HttpMethodConstraint。

  ServletSecurity註釋類型是在一個使用在servlet類上 用於強制安全約束。一個servlet安全註解可能有值和 httpMethodConstraint屬性。

  在HttpConstraint註釋類型定義了安全約束,只能分 配給ServletSecurity註解的值屬性。

  若HttpMethodConstraint屬性不存在於 ServletSecurity註釋內,由HttpConstraint註解施加的安 全約束適用於全部的HTTP方法。不然,安全約束將應 用於列舉HttpMethodContraint屬性定義的HTTP方法。 例如,下面的註解HttpConstraint決定了註解的servlet只 能由那些經理角色進行訪問:

@ServletSecurity(value = @HttpConstraint(rolesAllowed = "manager"))

  固然,註釋上述可改寫以下:

@ServletSecurity(@HttpConstraint(rolesAllowed = "manager"

  你仍然須要在部署描述符來聲明login-config元素, 以使容器能夠驗證用戶:

  設置transportGuarantee.confidential的HttpConstraint 標註到transportGuarantee屬性使servlet只能經過祕密渠 道,如SSL:

@ServletSecurity(@HttpConstraint(transportGuarantee = TransportGuarantee.CONFIDENTIAL))

  若是servlet和JSP容器接受這樣一個Servlet經過 HTTP請求時,它將瀏覽器重定向到HTTPS版本相同的 URL。

  該HttpMethodConstraint註釋類型指定一個安全約 束適用於任何的HTTP方法。它只能出現分配給 ServletSecurity註釋的HttpMethodConstraint屬性的數組 中。例如,下面的註解HttpMethodConstraint限制經過 HTTP訪問該註釋的servlet manager角色,對於其餘 HTTP方法,則不存在限制:

@ServletSecurity(httpMethodConstraints = {
@HttpMethodConstraint(value = "GET", rolesAllowed = "manage
r")
})

   請注意,若是rolesAllowed屬性在 HttpMethodConstraint註釋裏不存在,則對於指定的 HTTP方法沒有限制。例如,下面的ServletSecurity註釋 同時採用兩個約束。HttpConstraint註釋定義了能夠訪問 servlet的角色,而HttpMethodConstraint註解編寫了覆蓋 GET方法約束,且沒有rolesAllowed屬性。所以,該 servlet能夠被任何用戶經過GET方法訪問。在另外一方 面,經過其餘全部的HTTP方法訪問只能授予的經理角 色的用戶:

@ServletSecurity(value = @HttpConstraint(rolesAllowed = "manager"),
httpMethodConstraints = {@HttpMethodConstraint("GET")})

  然而,若是對HttpMethodConstraint註釋類型的 emptyrolesemantic屬性設置爲emptyrolesemantic. deny, 那麼方法是限制全部用戶。例如,servlet使用如下 ServletSecurity註釋的,防止經過Get方法訪問,可是允 許全部用戶成員的角色經過其餘HTTP方法訪問:

@ServletSecurity(value = @HttpConstraint(rolesAllowed = "member"),
httpMethodConstraints = {@HttpMethodConstraint(value = "GET",
emptyRoleSemantic = EmptyRoleSemantic.DENY)})

2. Servlet的安全API

  除了在上一節討論的註釋類型,程序的安全性也可 以在HttpServletRequest接口使用如下方法實現

java.lang.String getAuthType()

  返回用來保護servlet認證方案,若是沒有安全約束 則返回空。

java.lang.String getRemoteUser()

  返回發出此請求登陸用戶,若是用戶還沒有驗證則返 回空。

boolean isUserInRole(java.lang.String role

  返回一個指示用戶是否屬於指定的角色布爾值。

java.lang.Principal getUserPrincipal()

  返回包含當前經過驗證的用戶的細節信息的java、 security.principal,若是用戶沒有經過認證返回空。

boolean authenticate(HttpServletResponse response) throws
java.io.IOException

  經過指示瀏覽器顯示登陸表單來驗證用戶。

void login(java.lang.String userName, java.lang.String password) throws javax.servlet.ServletException

  試圖使用所提供的用戶名和密碼進行登陸。該方法 沒有返回,若是登陸失敗,它會拋出一個 ServletException異常。

void logout() throws javax.servlet.ServletException

  註銷用戶。

  ProgrammaticServlet是app12e應 用程序的一部分,演示如何使用編程的方式來驗證用 戶,相配套的部署描述符,描述符中聲明瞭一個採用摘要訪問認證的login-config元素。

ProgrammaticServlet類

package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = { "/prog" })
public class ProgrammaticServlet extends HttpServlet {
    private static final long serialVersionUID = 87620L;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 發送一個登錄驗證頁面給客戶端
        if (request.authenticate(response)) {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            out.println("Welcome");
        } else {
// user not authenticated
// do something
            System.out.println("User not authenticated");
        }
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
➥ http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <login-config>
        <auth-method>DIGEST</auth-method>
        <realm-name>Digest authentication</realm-name>
    </login-config>

</web-app>

  當用戶第一次請求servlet,用戶未經身份驗證和認 證方法返回false。做爲一個結果,servlet和JSP容器將 發送一個WWW-Authenticate頭,瀏覽器會顯示一個摘 要訪問認證登陸對話框。當用戶提交表單時使用正確的 用戶名和密碼進行身份驗證,該方法返回true,顯示歡 迎信息。

 

  

3.  

相關文章
相關標籤/搜索