配置Struts 2應用程序的安全功能
安全性是Web應用程序開發(fā)工作中最關鍵的問題之一。在基于servlet的應用程序里,保護應用程序資源的辦法有兩種:一是對應用程序進行配置(web.xml),二是使用Java代碼硬編碼到程序中。前一種方法使用配置文件,該方法很靈活,這是因為通過使用配置文件,無需改寫任何代碼就可以改變安全策略,是一種常見的手段。而Struts 2是基于servlet技術的,所以Struts 2的安全策略也可以使用配置文件進行靈活的配置。
配置安全策略時,有兩個概念需要清楚的區(qū)分 ,用戶和角色,簡單的說用戶為使用計算機的人,可以是個人或組織。角色是一個抽象的概念,泛指職務或者權限。例如,張三,李四,王五三個人,有職員、主管和經理三個職務(權限),張三是用戶,張三可以是主管職務,代表張三這個用戶含有主管的權利。
不同的servlet容器所提供的用戶和角色管理機制是不相同的。我使用的是Tomcat服務器,它提供的用戶和角色管理機制文件是在其安裝目錄下的conf目錄中的tomcat-users.xml文件,可以在這個文件里完成對用戶和角色的編輯。例如:
- <tomcat-users>
- <role rolename="tomcat"/>
- <role rolename="role1"/>
- <user username="tomcat" password="tomcat" roles="tomcat"/>
- <user username="both" password="tomcat" roles="tomcat,role1"/>
- <user username="role1" password="tomcat" roles="role1"/>
- </tomcat-users>
這個文件定義了2個角色(tomcat和role1)和3名用戶(tomcat、both和role1)。你可以在tomcat-users.xml文件里定義任意多個用戶和角色。
使用Struts 2保護應用程序的資源
Struts 2應用程序的安全策略是通過部署web.xml文件中的security-constraint元素實現(xiàn)的,該元素的語法定義:
- <!ELEMENT security-constraint (display-name?, web-resource-collection+, auth-constraint?, user-data-constraint?)>
- <!ELEMENT display-name (#PCDATA)>
- <!ELEMENT web-resource-collection (web-resource-name, description?, url-pattern*, http-method*)>
- <!ELEMENT auth-constraint (description?, role-name*)>
- <!ELEMENT user-data-constraint (description?, transport-guarantee)>
該語法說明了,security-constraint元素可以有一個可選的display-name子元素,至少一個web-resource-collection子元素,一個可選的auth-constraint子元素和一個可選的user-data-constraint子元素。
web-resource-collection子元素是用來列出打算保護的Web資源,具體的做法是為這些資源設置URL限制,它是通過設置web-resource-collection元素包含的子元素實現(xiàn)的:
◆ web-resource-name:是與受保護資源相關聯(lián)的名稱。該子元素為必須元素。
◆ description:對給定資源的描述。這個子元素為可選元素。
◆ url-pattern:用來設置URL表達式,與這個URL表達式相匹配的URL地址指向的資源將受到保護。該子元素為至少有一個,為必須元素。
◆ http-method:用來表明哪些HTTP方法將受到限制,例如設置為GET那么所有的GET請求就將受到限制。該元素為可選元素。
auth-constraint元素用于指定可以訪問該資源用戶角色集合。如果沒有指定auth-constraint元素,就將安全約束應用于所有角色。它包含下面幾個子元素:
◆ description:描述。該元素是可選元素。
◆ role-name:可以訪問保護資源的用戶角色。該元素可以有多個。
◆ user-data-constraint元素用來設置怎樣保護在客戶端和Web容器之間傳遞的數(shù)據(jù)。
◆ description: 描述??蛇x元素。
◆ transport-guarantee :該元素有以下幾個值
1. NONE,這意味著應用不需要傳輸保證。
2. INTEGRAL,意味著服務器和客戶端之間的數(shù)據(jù)必須以某種方式發(fā)送,而且在傳送中數(shù)據(jù)不能被篡改。
3. CONFIDENTIAL,這意味著傳輸?shù)臄?shù)據(jù)必須加密。
配置完畢security-constraint元素的基本信息,大致為下面的格式:
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>Admin Arew</web-resource-name>
- <url-pattern>*.action</url-pattern>
- </web-resource-collection>
- <auth-constraint>
- <role-name>myeclipseWeb</role-name>
- </auth-constraint>
- </security-constraint>
這個security-constraint元素的效果為:只要與表達式"*.action"匹配的請求不是來自擁有"myeclipseWeb"權限的用戶,Web容器就會阻斷它。在這里還可以使用http-method元素,阻斷特定方法的請求,因為沒有使用會阻斷所有方法提交的請求。
設置完安全策略后,還需要設置讓用戶有機會提供證明,證明自己有權限訪問這個受限資源的登陸方法。允許使用的登陸方法使用login-config元素設置,下面為login-config元素的語法定義:
- <!ELEMENT login-config (auth-method?, realm-name?, form-login-config?)>
- <!ELEMENT auth-method (#PCDATA)>
- <!ELEMENT realm-name (#PCDATA)>
- <!ELEMENT form-login-config (form-login-page, form-error-page)>
login-config子元素的描述如下:
◆ auth-method指定用來驗證用戶身份的方法。它的值為下面的一個:BASIC、DIGEST、FORM或 CLIENT-CERT
◆ realm-name指定HTTP Basic驗證中在標準登陸框中顯示的一條提示。
◆ form-login-config元素是在<auth-method>元素值為"FORM"時使用的。它是指定基于表單的登錄中應該使用的登錄頁面和出錯頁面。如果沒有使用基于表單的驗證,則忽略這些元素。這個元素的定義如下,其中form-login-page用于指定顯示登錄頁面的資源路徑, form-error-page則用于指定用戶登錄失敗時顯示出錯頁面的資源路徑。
- <!ELEMENT form-login-config (form-login-page, form-error-page)>
- <!ELEMENT form-login-page (#PCDATA)>
- <!ELEMENT form-error-page (#PCDATA)>
設置完登陸方法后,還應該使用security-role元素,注冊允許用來訪問受保護資源所有角色。在該元素內部使用一個role-name子元素來注冊一個角色。例如:
- <security-role>
- <role-name>myeclipseWeb</role-name>
- </security-role>
注冊了一個"myeclipseWeb"的角色。
演示示例:使用BASIC登陸方法驗證用戶身份
1.我使用的Servlet容器是Tomcat,找到它的目錄下conf目錄中的tomcat-users.xml文件打開內容如下:
- <?xml version='1.0' encoding='utf-8'?>
- <tomcat-users>
- <role rolename="myeclipseWeb"/>
- <role rolename="myeclipseWebservices"/>
- <user username="webservices" password="webservices-pwd" roles="myeclipseWebservices"/>
- <user username="admin" password="admin-pwd" roles="myeclipseWeb,myeclipseWebservices"/>
- <user username="web" password="web-pwd" roles="myeclipseWeb"/>
- </tomcat-users>
我使用的IDE是myEclipse9.0,它配置好Tomcat下的tomcat-users.xml文件內容如上,我直接使用它了,你也可以添加自己的角色和用戶。該文件定義了2個角色和3個用戶,每一個用戶都由自己的角色(或者說權限,可以有多重權限)。
2.創(chuàng)建Web項目,找到web.xml,配置它,使它支持Struts 2并且啟動Struts 2的安全策略
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app id="WebApp_9" version="2.4"
- xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
- <display-name>Struts Blank</display-name>
- <filter>
- <filter-name>struts2</filter-name>
- <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>struts2</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- </welcome-file-list>
- <!-- 配置應用程序需要保護的資源與什么角色才可以訪問它 -->
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>Admin Arew</web-resource-name>
- <url-pattern>*.action</url-pattern>
- </web-resource-collection>
- <auth-constraint>
- <role-name>myeclipseWeb</role-name>
- </auth-constraint>
- </security-constraint>
- <!-- 注冊可以訪問保護資源的角色 -->
- <security-role>
- <role-name>myeclipseWeb</role-name>
- </security-role>
- <security-role>
- <role-name>myeclipseWebservices</role-name>
- </security-role>
- <!-- 設置登錄方法 -->
- <login-config>
- <auth-method>BASIC</auth-method>
- <realm-name>User Basic Authentication</realm-name>
- </login-config>
- </web-app>
3. 創(chuàng)建接收一個字段信息的動作類:
- public class SecureAction extends ActionSupport {
- private static final long serialVersionUID = 1961430702313132722L;
- private String username;
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- @Override
- public String execute()
- {
- return SUCCESS;
- }
- }
4. 創(chuàng)建struts.xml配置文件,聲明動作
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
- <struts>
- <package name="securePackage" extends="struts-default">
- <action name="secure" class="struts2.action.SecureAction">
- <result name="success">/index.jsp</result>
- </action>
- </package>
- </struts>
5. 創(chuàng)建輸入頁面input.jsp和結果頁面index.jsp
input.jsp:
- <body>
- <s:form action="secure">
- <s:textfield name="username" label="Enter your name"></s:textfield>
- <s:submit value="submit"></s:submit>
- </s:form>
- </body>
index.jsp
- <body>
- <s:property value="username"/>,Welcome
- </body>
6.測試效果,在瀏覽器輸入:http://localhost:8081/SecureTest/input.jsp,得到如下界面:輸入"Tom",點擊"submit"按鈕,查看效果:
看到了登陸框了吧,此時我們要訪問的資源是一個受限資源所以要求權限驗證,還記得我們的用戶表吧,查看用戶表輸入用戶信息查看結果:
輸入"webservices"與"webservices-pwd"的用戶信息:
提示了一個"403"錯誤,這是因為雖然用戶信息正確,但是"webservices"用戶的沒有"myeclipseWeb"權限。
這次輸入一個不存在的用戶信息:
這次獲得了一個"401"錯誤,這是登陸失敗的提示結果,這里會因瀏覽器的不同而需要不同次數(shù)的失敗登陸才會得到這個結果。
接下來輸入一個正確的用戶,并且擁有"webservices"權限的用戶信息:
點擊"確定",獲得如下結果:
可以看到,我們成功的訪問了受保護的資源。若要傳中文字,解決方案我已經在前面"配置Struts2"時介紹過了,需要修改Struts 2默認的編碼方式還需要修改頁面的編碼方式,都改為"GBK"。
原文鏈接:http://www.cnblogs.com/suxiaolei/archive/2011/11/02/2233601.html
【編輯推薦】