Tomcat容器管理安全的幾種驗證方式

當訪問服務器中受保護的資源時,容器管理的驗證方法可以控制確認用戶身份的方式。Tomcat支持四種容器管理的安全防護,它們是:

  • BASIC(基本驗證):通過HTTP驗證,需要提供base64編碼文本的用戶口令
  • DIGEST(摘要驗證):通過HTTP驗證,需要提供摘要編碼字符串的用戶口令
  • FORM(表單驗證):在網頁的表單上要求提供密碼
  • CLIENT-CERT(客戶端證書驗證):以客戶端證書來確認用戶的身份

 基本驗證

當web.xml文件中的auth-method元素設置爲BASIC時,表明應用使用的是基本驗證,每次瀏覽器請求受保護的Web應用資源時,Tomcat都會使用HTTP基本驗證向瀏覽器索取用戶名和密碼(以頁面彈窗的方式)。使用這種驗證方法,所有的密碼都會以base64編碼的文本在網絡上傳輸。

先看下項目結構(我用Maven管理的依賴):

其中,protect/protect.jsp是被保護的,需要授權訪問。

說明:本文提到的tomcat-users.xml,server.xml等文件,如果是在Eclipse中啓動tomcat,則這些文件在Eclipse中的Servers工程下對應的tomcat下,如圖:

本文提到的web.xml是指項目自己的web.xml,而非Servers項目下Tomcat中的web.xml

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<security-constraint>
    <web-resource-collection>
        <http-method>GET</http-method>
        <web-resource-name>tomcat protect page</web-resource-name>
        <!-- /protect目錄下的所有資源是受保護的 -->
        <url-pattern>/protect/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <!-- 這裏的member要與tomcat-user.xml中配置的role一致 -->
        <role-name>member</role-name>
    </auth-constraint>
</security-constraint>
<login-config>
    <!-- 驗證方式,可選的值爲: "BASIC", "DIGEST", "FORM", "CLIENT-CERT" -->
    <auth-method>BASIC</auth-method>
    <!-- 使用的Realm名字,注意這裏不能有空格 -->
    <realm-name>MyConstraints</realm-name>
</login-config>

tomcat-user.xml(注意如果是在Eclipse中啓動tomcat,這個tomcat-user.xml在Eclipse中的Servers工程下)

1
2
3
<role rolename="member"/>
<!-- member角色下有一個叫alvis的用戶,密碼爲pwd -->
<user username="alvis" password="pwd" roles="member"/>

重啓tomcat後,訪問protect目錄下的資源,情況是這樣的:

輸入賬戶alvis,密碼pwd後,訪問成功(當然,非protect目錄下的資源是可以直接訪問的):

摘要驗證

當web.xml文件中的auth-method元素設置爲DIGEST時,表明應用使用的是摘要驗證。還是上面的例子,看配置:

web.xml和基本驗證一樣,只是auth-method修改爲DIGEST,此處不贅述。

server.xml中的UserDatabaseRealm(如果tomcat使用的是其他Realm,也一樣的)裏增加digest屬性:

接下來,要生成tomcat可識別的MD5密碼。方式有兩種,正如官網描述:

To calculate the digested value of a cleartext password, two convenience techniques are supported:

  • If you are writing an application that needs to calculate digested passwords dynamically, call the static Digest()method of the org.apache.catalina.realm.RealmBase class, passing the cleartext password and the digest algorithm name as arguments. This method will return the digested password.
  • If you want to execute a command line utility to calculate the digested password, simply execute
    <code>CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} {cleartext-password} </code>

    and the digested version of this cleartext password will be returned to standard output.

方式一:用代碼來生成:

1
2
3
4
5
6
7
8
9
import org.apache.catalina.realm.RealmBase;
 
public class T {
    public static void main(String[] args) {
        //參數1:要加密的字符串;參數2:加密算法;參數3:字符串的編碼
        String base = RealmBase.Digest("alvis:MyConstraints:pwd", "MD5", null);
        System.out.println(base);
    }
}

由於RealmBase類在catalina.jar包中,如果項目中沒有這個類,可在項目上右鍵–>Java Build Path–> Libraries–>Add Library–>選擇Server Runtime–>選擇Apache Tomcat V8.0(其實7.0也行),如圖:

方式二:用腳本來生成:

在tomcat/bin目錄下有個digest.sh(Linux系統)或digest.bat(Windows系統)腳本,運行這個腳本,傳入摘要算法和參數即可,這裏我在Windows系統上運行,如圖:

這裏的-a指定摘要算法爲MD5,要特別注意這裏的參數是:{用戶名}:{Realm名}:{密碼明文}。用戶名就是tomcat-users.xml中配置的<user>名字(這裏爲alvis),Realm名是在web.xml中配置的<realm-name>(這裏爲MyConstraints),密碼明文即該用戶用於登錄的密碼(我這裏設爲pwd)。

只有這樣的參數加密後的密碼,在tomcat-users.xml中配置纔有效,否則是登錄不了的。由於我是參考《Tomcat權威指南(第二版)》的步驟做的,之前試了很久都不知道爲什麼登錄不了,結果在官網找到答案,是這麼描述的:

If using digested passwords with DIGEST authentication, the cleartext used to generate the digest is different and the digest must use the MD5 algorithm. In the examples above {cleartext-password} must be replaced with {username}:{realm}:{cleartext-password}. For example, in a development environment this might take the form testUser:Authentication required:testPassword. The value for {realm} is taken from the <realm-name> element of the web application’s <login-config>. If not specified in web.xml, the default value of Authentication required is used.

大意是說,如果使用DIGEST方式驗證,用於生成摘要的明文必須被替換爲這種格式。實踐出真知,所以還是不能完全看書啊,動手實踐纔是實在的。

然後就是在tomcat-users.xml中配置生成的密碼(通過下方的截圖,可以比較password跟上方digest.bat腳本生成的密碼是否一致):

之後重啓tomcat,效果自然是跟使用基本驗證的效果一樣了。

表單驗證

當web.xml文件中的auth-method元素設置爲FORM時,表明應用使用的是表單驗證。當用戶請求Web應用程序受保護的資源時,表單驗證會跳轉至配置的登錄頁面。當登錄失敗時,還需要一個驗證失敗的頁面,還是上面的例子,看配置:

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<security-constraint>
    <web-resource-collection>
        <http-method>GET</http-method>
        <web-resource-name>tomcat member part</web-resource-name>
        <url-pattern>/protect/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>member</role-name>
    </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>MyConstraints</realm-name>
    <form-login-config>
        <form-login-page>/form/login.html</form-login-page>
        <form-error-page>/form/error.html</form-error-page>
    </form-login-config>
</login-config>

這裏的form/login.html是用於登錄的頁面,而form/error.html則是驗證失敗後跳轉到的頁面(這兩個頁面在上方的工程結構圖中已經有了)。

login.html

1
2
3
4
5
6
7
8
9
10
11
12
<html>
    <body>
    <h2>Login Page.</h2>
 
    <form method="post" action="j_security_check" name="loginForm">
        <input type="text" name="j_username" />
        <input type="password" name="j_password" />
        <input type="submit" value="Login" />
    </form>
 
    </body>
</html>

注意:這裏form的action=”j_security_check“,賬號的name=”j_username“和密碼的name=”j_password“都是不可變的,否則配置的驗證規則不起作用。

server.xml中,要去掉Realm中添加的“digest=MD5”這個屬性:

tomcat-users.xml中使用明文保存密碼:

效果(僅在訪問protect目錄下的資源時纔出現Login Page):

輸入錯誤的賬號和密碼,跳轉至form/error.html頁面:

輸入正確的賬號和密碼,跳轉至受保護的頁面:

客戶端證書驗證

待續

Demo下載:

鏈接: http://pan.baidu.com/s/1gfnqVdT 密碼: pubw

參考頁面:

https://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html

發佈了19 篇原創文章 · 獲贊 9 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章