當訪問服務器中受保護的資源時,容器管理的驗證方法能夠控制確認用戶身份的方式。Tomcat支持四種容器管理的安全防禦,它們是:html
當web.xml文件中的auth-method元素設置爲BASIC時,代表應用使用的是基本驗證,每次瀏覽器請求受保護的Web應用資源時,Tomcat都會使用HTTP基本驗證向瀏覽器索取用戶名和密碼(以頁面彈窗的方式)。使用這種驗證方法,全部的密碼都會以base64編碼的文本在網絡上傳輸。web
先看下項目結構(我用Maven管理的依賴):算法
其中,protect/protect.jsp是被保護的,須要受權訪問。apache
說明:本文提到的tomcat-users.xml,server.xml等文件,若是是在Eclipse中啓動tomcat,則這些文件在Eclipse中的Servers工程下對應的tomcat下,如圖:瀏覽器
而本文提到的web.xml是指項目本身的web.xml,而非Servers項目下Tomcat中的web.xml。tomcat
web.xml安全
<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工程下)服務器
<role rolename="member"/> <!-- member角色下有一個叫alvis的用戶,密碼爲pwd --> <user username="alvis" password="pwd" roles="member"/>
重啓tomcat後,訪問protect目錄下的資源,狀況是這樣的:網絡
輸入帳戶alvis,密碼pwd後,訪問成功(固然,非protect目錄下的資源是能夠直接訪問的):app
當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 theorg.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
CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} {cleartext-password}and the digested version of this cleartext password will be returned to standard output.
方式一:用代碼來生成:
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 formtestUser: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 ofAuthentication required
is used.
大意是說,若是使用DIGEST方式驗證,用於生成摘要的明文必須被替換爲這種格式。實踐出真知,因此仍是不能徹底看書啊,動手實踐纔是實在的。
而後就是在tomcat-users.xml中配置生成的密碼(經過下方的截圖,能夠比較password跟上方digest.bat腳本生成的密碼是否一致):
以後重啓tomcat,效果天然是跟使用基本驗證的效果同樣了。
當web.xml文件中的auth-method元素設置爲FORM時,代表應用使用的是表單驗證。當用戶請求Web應用程序受保護的資源時,表單驗證會跳轉至配置的登陸頁面。當登陸失敗時,還須要一個驗證失敗的頁面,仍是上面的例子,看配置:
web.xml
<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
<html> <body> <h2>Login Page.</h2> <form method="post" action="j_security_check" name="loginForm"> <input type="text" name="j_username" /><br> <input type="password" name="j_password" /><br> <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
參考頁面: