|
◆ 背景 大多數(shù)組織把信息資料當(dāng)作他們的最寶貴的資產(chǎn)。保護(hù)信息的工作不僅僅是象開(kāi)發(fā)者和管理員似的一個(gè)專職的工作而已。信息的保護(hù)必須從許多不同的角度實(shí)施。數(shù)據(jù)庫(kù),用戶界面和商業(yè)層只是這些需要你注意的關(guān)鍵領(lǐng)域的某些方面。甚至通往服務(wù)器機(jī)房的門都必須被鎖住。更重要的是,一旦這些數(shù)據(jù)經(jīng)由因特網(wǎng)離開(kāi)了這些建筑物,它的安全就會(huì)被一些很有才能的在網(wǎng)絡(luò)上用電子手段刺探的人危及。 在本方法中,我們示范怎樣在容器中啟動(dòng)Secure Socket Layer (SSL)。另外,我們?yōu)槟憬榻BStruts SSL 的擴(kuò)展,HTTP/HTTPS切換庫(kù)——一個(gè)允許你聲明哪些Action啟用了SSL 的程序包。這個(gè)很好用的程序包允許你在SSL-激活的Action和禁止的Action之間很容易地轉(zhuǎn)換。 進(jìn)入本方法之前,讓我們涉及一些SSL 基礎(chǔ)。SSL原來(lái)是一個(gè)由Netscape 開(kāi)發(fā)的網(wǎng)絡(luò)協(xié)議,來(lái)提供認(rèn)證和傳輸保密性。SSL 協(xié)議屬于TCP/IP之上的網(wǎng)絡(luò)層,但是低于應(yīng)用協(xié)議,比如HTTP ,LDAP和IMAP。在傳送前客戶端檢驗(yàn)服務(wù)器的身份。 類似的,服務(wù)器端也可能可選地檢驗(yàn)客戶端的身份。為了阻斷數(shù)字偷聽(tīng)者的努力,這兩個(gè)主機(jī)就一個(gè)密碼算法達(dá)成一致協(xié)議,通常叫做一個(gè)密碼,來(lái)加密和解密傳送的數(shù)據(jù)。除提供機(jī)密性之外,SSL 對(duì)傳送過(guò)程進(jìn)行審計(jì),來(lái)保證傳輸?shù)臄?shù)據(jù)在途中未被篡改。整個(gè)SSL 的工作方式超出了這個(gè)方法的范圍,但是我們鼓勵(lì)你利用一些在資源部分提到的資源探索SSL。 大多數(shù)容器,包括Tomcat ,提供SSL 服務(wù)。在你容器上啟動(dòng)SSL 確保你的通訊是安全的和不被篡改的。容器能通過(guò)檢查URL 方案識(shí)別出SSL 通訊。URL 方案是URL 中冒號(hào)前面的那部分。HTTP 非保密協(xié)議是用冒號(hào)之前的“HTTP”識(shí)別的。例如,http://127.0.0.1指出一個(gè)非保密http 協(xié)議。一個(gè)“s”放置在http 后,來(lái)表明該請(qǐng)求希望使用SSL 傳送。例如,https://127.0.0.1是用于一個(gè)SSL http 請(qǐng)求的適當(dāng)?shù)腢RL。 許多應(yīng)用程序兼具SSL 和非SSL連接。這里面的挑戰(zhàn)是當(dāng)你要一個(gè)安全通信的時(shí)候,怎樣格式化你的連接成為SSL 。作為默認(rèn),Struts 鏈接標(biāo)簽使用與你正在瀏覽的當(dāng)前頁(yè)面相同的URI 方案。所以,如何從一個(gè)安全的頁(yè)面到一個(gè)不安全的頁(yè)面建立一個(gè)鏈接,或者反過(guò)來(lái)怎么做呢?一個(gè)選擇是建立你自己的鏈接標(biāo)簽來(lái)寫SSL 鏈接,但是這會(huì)迅速地導(dǎo)致維護(hù)的負(fù)擔(dān),只要你需要把鏈接從一個(gè)轉(zhuǎn)變到另一個(gè)的任何時(shí)候。現(xiàn)在如果你能通過(guò)在struts-config.xml 文件中聲明來(lái)做這個(gè),你會(huì)成為一個(gè)幸福的露營(yíng)者了。你可以使用標(biāo)簽來(lái)寫你的鏈接,但是一旦情況發(fā)生變化,你可以在struts-config.xml 文件中聲明性地改變它們。很幸運(yùn),那剛好是Struts SSL HTTP/HTTPS 切換擴(kuò)展庫(kù)為你做的。在這個(gè)方法中,我們展示怎樣用Tomcat 設(shè)立SSL。然后我們展示怎樣在你的應(yīng)用程序中設(shè)立和使用ssl-ext 來(lái)加密網(wǎng)上傳輸?shù)臄?shù)據(jù)。完整的SSL 認(rèn)證的說(shuō)明超出了本書的范圍;實(shí)際上,我們集中在Struts 開(kāi)發(fā)的SSL方面。 ◆ 方法 本方法的實(shí)現(xiàn)被分成三個(gè)部分。在前邊部分我們展示怎樣在Tomcat 上啟動(dòng)SSL 。接下來(lái),我們描述究竟需要做什么來(lái)完成在你的應(yīng)用程序中安裝SSL-ext。最后,我們?cè)诖a中應(yīng)用SSL-ext。現(xiàn)在開(kāi)始! 步驟1:在Tomcat 上啟動(dòng)SSL 1 從http://java./products/jsse/下載并安裝JSSE 1.0.2(或者更新的版本)。此網(wǎng)址告訴你安裝JSSE必須知道的所有動(dòng)作。注意,Java 2 SDK Standard Edition v1.4已經(jīng)預(yù)先捆綁了JSSE。如果你正在使用JDK v1.4,你可以跳個(gè)過(guò)這個(gè)步驟。 2 創(chuàng)建一個(gè)證書keystore(密鑰倉(cāng)庫(kù))。鍵入以下命令之一: 對(duì)Windows: %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA 對(duì)UNIX: $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA 你會(huì)被問(wèn)到許多問(wèn)題。作為練習(xí)目的,僅僅鍵入對(duì)你來(lái)說(shuō)有意義的無(wú)論什么都可以。當(dāng)要實(shí)現(xiàn)到一個(gè)受控環(huán)境中時(shí),找你的系統(tǒng)管理員。 3 從conf/server.xml 中取消SSL HTTP/1.1 Connector 的注釋。該被取消注釋的連接器應(yīng)該看起來(lái)像這樣(特別地,記下端口號(hào),隨后必須知道): <Connector className="org.apache.coyote.tomcat4.CoyoteConnector" port="8443" minProcessors="5" maxProcessors="75" enableLookups="true" acceptCount="10" debug="0" scheme="https" secure="true" useURIValidationHack="false"> <Factory className="org.apache.coyote.tomcat4.CoyoteServerSocketFactory" clientAuth="false" protocol="TLS" /> </Connector> 4 重新啟動(dòng)Tomcat。用瀏覽器訪問(wèn)https://127.0.0.1:8443來(lái)確定所有動(dòng)作如設(shè)計(jì)運(yùn)行。如果Tomcat 顯示該頁(yè)面,那么就奏效了。 祝賀,你已經(jīng)在Tomcat 上激活了SSL。 步驟2:為應(yīng)用程序設(shè)置Struts SSL HTTP/HTTPS 切換擴(kuò)展(SSL-ext) 因?yàn)閟sl-ext 是一個(gè)Struts 擴(kuò)展庫(kù),它的安裝與Struts類似就不奇怪了。如果你已經(jīng)安裝了Struts,以下用法說(shuō)明會(huì)似曾相識(shí)。 1 從http://sslext. 下載ssl-ext 包。該包包含一個(gè)可工作的樣例應(yīng)用程序。把下載包Unzip 到Tomcat webapps 目錄。在以下步驟中,你要從樣例應(yīng)用程序復(fù)制許多文件來(lái)創(chuàng)建你自己的ssl-ext 應(yīng)用程序。 2 把sslext.jar 文件從樣例應(yīng)用程序復(fù)制到WEB-INF/lib 目錄中。 3 把sslext.tld 文件從樣例應(yīng)用程序復(fù)制到你的WEB-INF/lib 目錄中。 4 把以下片斷和其他taglib一起放在web.xml 文件中: <taglib> <taglib-uri>/WEB-INF/sslext.tld</taglib-uri> <taglib-location>/WEB-INF/sslext.tld</taglib-location> </taglib> 5 把插件標(biāo)簽添加到struts-config.xml 文件中。特別記下httpsPort 屬性。它必須與用來(lái)配置Tomcat 的相同(步驟1,說(shuō)明3)。如你可能預(yù)期的,該httpPort 屬性應(yīng)該和在conf/server.xml 中找到的Tomcat 配置相配。下列兩個(gè)定義的值是Tomcat 的值。 <plug-in className="org.apache.struts.action.SecurePlugIn"> <set-property property="httpPort" value="8080"/> <set-property property="httpsPort" value="8443"/> <set-property property="enable" value="true"/> </plug-in> 做完這些,你隨時(shí)可以開(kāi)始使用ssl-ext了。 步驟3:使用ssl-ext 建立一個(gè)應(yīng)用程序 我們通過(guò)建立一個(gè)應(yīng)用程序來(lái)示范ssl-ext 運(yùn)轉(zhuǎn)。在這個(gè)步驟中,我們展示ssl-ext 是如何被用來(lái)為指向ssl 安全頁(yè)面的鏈接格式化URL 的。相反的,我們示范為指向普通的非SSL頁(yè)面的鏈接格式化URL。我們將知道給頁(yè)面提供安全保障是通過(guò)對(duì)struts-config.xml 做一個(gè)小的改變完成的。清單7.6 展示struts-config.xml 對(duì)應(yīng)一個(gè)示例應(yīng)用程序的動(dòng)作映射。 清單7.6 Struts-config.xml <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta./struts/dtds/struts-config_1_1.dtd"> <struts-config> <global-forwards type="org.apache.struts.action.ActionForward"> <forward name="unsecured" path="/unsecured.do"/> <forward name="secured" path="/secured.do"/> <forward name="menu" path="/menu.do"/> </global-forwards> <form-beans> <form-bean name="dummyForm" type="com.strutsrecipes.ssl.forms.Dummy" /> </form-beans> <action-mappings type="org.apache.struts.config.SecureActionConfig"> ? <action path="/menu" type="org.apache.struts.actions.ForwardAction" parameter="/WEB-INF/pages/menu.jsp"> <set-property property="secure" value="false"/> </action> <action path="/unsecured" type="org.apache.struts.actions.ForwardAction" parameter="/WEB-INF/pages/unsecured.jsp"> <set-property property="secure" value="false"/> ? </action> <action path="/secured" type="org.apache.struts.actions.ForwardAction" parameter="/WEB-INF/pages/secured.jsp"> <set-property property="secure" value="true"/> ? </action> <action path="/securesubmit" type="org.apache.struts.actions.ForwardAction" name="dummyForm" parameter="/WEB-INF/pages/securesubmit.jsp"> <set-property property="secure" value="true"/> ? </action> <action path="/unsecuresubmit" type="org.apache.struts.actions.ForwardAction" name="dummyForm" parameter="/WEB-INF/pages/unsecuresubmit.jsp"> <set-property property="secure" value="false"/> ? </action> </action-mappings> <plug-in className="org.apache.struts.action.SecurePlugIn"> <set-property property="httpPort" value="8080"/> <set-property property="httpsPort" value="8443"/> <set-property property="enable" value="true"/> </plug-in> </struts-config> 要用SSL 使一個(gè)Action 安全,把一個(gè)<set-property>標(biāo)簽嵌套在Action 標(biāo)簽內(nèi)。 該property 屬性的值永遠(yuǎn)是secure。該值屬性的true 值表明我們需要URL通過(guò)設(shè)置URI 方案“https”來(lái)發(fā)出一個(gè)SSL 請(qǐng)求。類似的,false 值表明該頁(yè)面是普通的不安全的頁(yè)面;該URI 方案應(yīng)該是“http”。一個(gè)any 值默認(rèn)表示采用當(dāng)前頁(yè)的方案。雖然你可以使 用一個(gè)普通的Struts 鏈接標(biāo)簽達(dá)到相同效果,但是該any 值讓你可以通過(guò)修改Struts-config 文件把它改成true 或者false 。 因?yàn)樵摪踩珜傩圆槐荒J(rèn)動(dòng)作映射支持,我們需要在(?處)重載它。清單7.7示范ssl-ext 鏈接標(biāo)簽如何被用來(lái)產(chǎn)生一個(gè)協(xié)議格式的URL 。 清單7.7 menu.jsp: JSP 使用 ssl-ext 鏈接標(biāo)簽 <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> ? <html:html> <h1>SSL: Menu</h1> <h2>Links</h2> <br><sslext:link forward="unsecured">unsecured</sslext:link> ? <br><sslext:link forward="secured">secured</sslext:link> ? <h2>submit to secured</h2> <sslext:form action="/securesubmit" > ? <br><html:text property="name" value=""/> <html:submit/> </sslext:form> <h2>submit to unsecured</h2> <sslext:form action="/unsecuresubmit" > <br><html:text property="name" value=""/> <html:submit/> </sslext:form> </html:html> 指向安全頁(yè)面的鏈接前綴https ,指向不安全的的頁(yè)面的鏈接被格式化成通常的http 。例如,在?處的鏈接顯示為“不安全的”http://127.0.0.1:8080/ssl/unsecured.do,而在?處的鏈接顯示為“安全的”https://127.0.0.1:8443/ssl/secured.do。 在清單7.7中最顯著的結(jié)果是我們從未指定頁(yè)面使用SSL,是否是安全的。該信息是定義在struts-configxml 文件中的。在清單7.7中?處的鏈接標(biāo)簽映射到清單7.6的?處。相似的,?處映射到?處,?處映射到?處, 提交工作以大體上相同的方式進(jìn)行,只是你必須從ssl-ext 名字空間(?處)( 到這里,應(yīng)用ssl-ext 的過(guò)程在上述步驟中得到完全解決。 ◆ 討論 因?yàn)椴襟E1和步驟2是顯而易見(jiàn)的,我們無(wú)需回顧那些部分。步驟3更有意思得多,并且值得仔細(xì)考察。JSP 的工作很簡(jiǎn)單,不考慮sslext 名字空間的話,它看起來(lái)幾乎無(wú)異于任何Struts JSP 。代替用Struts 鏈接標(biāo)簽寫鏈接的是我們使用sslext 名字空間當(dāng)中相同的標(biāo)簽。在這些場(chǎng)景后面,這些標(biāo)簽是使用動(dòng)作映射來(lái)把URI 方案設(shè)置為http 或者h(yuǎn)ttps 的。要用https 寫URL,把動(dòng)作映射上的secure 屬性設(shè)置為true。要把URL 寫成“http”,把它設(shè)置為false。提交的過(guò)程也是一樣,只是你使用sslext 名字空間的表單標(biāo)簽而不是Struts 的html 名字空間。 還有一個(gè)標(biāo)簽我們尚未討論過(guò)。pageScheme標(biāo)簽使用secure屬性 來(lái)強(qiáng)制一個(gè)到http 或者h(yuǎn)ttps 的重定向。例如,一個(gè)到<sslext:pageScheme secure="false">的頁(yè)面的https 請(qǐng)求重定向該請(qǐng)求到http,而不管實(shí)際上該請(qǐng)求是用https發(fā)起的。 如果沒(méi)有ssl-ext,用以保證URL 使用正確前綴方案的工作將會(huì)更加困難。代替通過(guò)在JSP 中修整每個(gè)ssl 鏈接來(lái)處理這個(gè)問(wèn)題的是,我們可以從struts-conf. xml 文件中來(lái)管理它。如此,維護(hù)性方面的報(bào)償是很客觀的。例如,如果我們有到相同Struts Action 的20個(gè)鏈接,那么為了改變鏈接以使用SSL,必須對(duì)20個(gè)JSP 做改變。同等的改變?cè)趕sl-ext 下只需要對(duì)struts-config.xml的僅僅一個(gè)改動(dòng)!犯太多罪過(guò)的是人,避免錯(cuò)誤的是神。 最優(yōu)方法 審慎地使用SSL——SSL 是一個(gè)認(rèn)證和使應(yīng)用程序安全的已被證實(shí)的、可靠的、靈活的,并且流行的辦法,但是你應(yīng)該僅當(dāng)需要時(shí)才使用它。所有SSL 的傳送都加密并解密數(shù)據(jù)。取決于選擇的密碼,這些運(yùn)算會(huì)影響應(yīng)用程序的性能。 ◆ 參考 n [SSLDOC] SSL Overview n [SSLEXT] SSL Extension for Struts HTTP/HTTPS switching n [SSLSPEC] SSL Specification n [SSLTOM] SSL Tomcat Configuration n [URI] W3 URI Specification |
|
|