切换到SSL再切换回来

原文链接:http://hi.baidu.com/jcjxwxb/blog/item/a4a6f301b4416e06738da598.html

Switch to SSL and back again

◆ 问题

怎样在应用程序中使用SSL。

◆ 背景

大多数组织把信息资料当作他们的最宝贵的资产。保护信息的工作不仅仅是象开发者和管理员似的一个专职的工作而已。信息的保护必须从许多不同的角度实施。数据库,用户界面和商业层只是这些需要你注意的关键领域的某些方面。甚至通往服务器机房的门都必须被锁住。更重要的是,一旦这些数据经由因特网离开了这些建筑物,它的安全就会被一些很有才能的在网络上用电子手段刺探的人危及。

在本方法中,我们示范怎样在容器中启动Secure Socket Layer (SSL)。另外,我们为你介绍Struts SSL 的扩展,HTTP/HTTPS切换库——一个允许你声明哪些Action启用了SSL 的程序包。这个很好用的程序包允许你在SSL-激活的Action和禁止的Action之间很容易地转换。

进入本方法之前,让我们涉及一些SSL 基础。SSL原来是一个由Netscape 开发的网络协议,来提供认证和传输保密性。SSL 协议属于TCP/IP之上的网络层,但是低于应用协议,比如HTTP ,LDAP和IMAP。在传送前客户端检验服务器的身份。 类似的,服务器端也可能可选地检验客户端的身份。为了阻断数字偷听者的努力,这两个主机就一个密码算法达成一致协议,通常叫做一个密码,来加密和解密传送的数据。除提供机密性之外,SSL 对传送过程进行审计,来保证传输的数据在途中未被篡改。整个SSL 的工作方式超出了这个方法的范围,但是我们鼓励你利用一些在资源部分提到的资源探索SSL。

大多数容器,包括Tomcat ,提供SSL 服务。在你容器上启动SSL 确保你的通讯是安全的和不被篡改的。容器能通过检查URL 方案识别出SSL 通讯。URL 方案是URL 中冒号前面的那部分。HTTP 非保密协议是用冒号之前的“HTTP”识别的。例如,http://127.0.0.1指出一个非保密http 协议。一个“s”放置在http 后,来表明该请求希望使用SSL 传送。例如,https://127.0.0.1是用于一个SSL http 请求的适当的URL。

许多应用程序兼具SSL 和非SSL连接。这里面的挑战是当你要一个安全通信的时候,怎样格式化你的连接成为SSL 。作为默认,Struts 链接标签使用与你正在浏览的当前页面相同的URI 方案。所以,如何从一个安全的页面到一个不安全的页面建立一个链接,或者反过来怎么做呢?一个选择是建立你自己的链接标签来写SSL 链接,但是这会迅速地导致维护的负担,只要你需要把链接从一个转变到另一个的任何时候。现在如果你能通过在struts-config.xml 文件中声明来做这个,你会成为一个幸福的露营者了。你可以使用标签来写你的链接,但是一旦情况发生变化,你可以在struts-config.xml 文件中声明性地改变它们。很幸运,那刚好是Struts SSL HTTP/HTTPS 切换扩展库为你做的。在这个方法中,我们展示怎样用Tomcat 设立SSL。然后我们展示怎样在你的应用程序中设立和使用ssl-ext 来加密网上传输的数据。完整的SSL 认证的说明超出了本书的范围;实际上,我们集中在Struts 开发的SSL方面。

◆ 方法

本方法的实现被分成三个部分。在前边部分我们展示怎样在Tomcat 上启动SSL 。接下来,我们描述究竟需要做什么来完成在你的应用程序中安装SSL-ext。最后,我们在代码中应用SSL-ext。现在开始!

步骤1:在Tomcat 上启动SSL

1    从http://java.sun.com/products/jsse/下载并安装JSSE 1.0.2(或者更新的版本)。此网址告诉你安装JSSE必须知道的所有动作。注意,Java 2 SDK Standard Edition v1.4已经预先捆绑了JSSE。如果你正在使用JDK v1.4,你可以跳个过这个步骤。

2    创建一个证书keystore(密钥仓库)。键入以下命令之一:

对Windows:

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA -keystore D:\server.keystore -validity 365

对UNIX: $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA

你会被问到许多问题。作为练习目的,仅仅键入对你来说有意义的无论什么都可以。当要实现到一个受控环境中时,找你的系统管理员。

3    从conf/server.xml 中取消SSL HTTP/1.1 Connector 的注释。该被取消注释的连接器应该看起来像这样(特别地,记下端口号,随后必须知道):

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="D:/server.keystore"
               keystorePass="changeit" />
    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

4    重新启动Tomcat。用浏览器访问https://127.0.0.1:8443来确定所有动作如设计运行。如果Tomcat 显示该页面,那么就奏效了。

祝贺,你已经在Tomcat 上激活了SSL。

步骤2:为应用程序设置Struts SSL HTTP/HTTPS 切换扩展(SSL-ext

因为ssl-ext 是一个Struts 扩展库,它的安装与Struts类似就不奇怪了。如果你已经安装了Struts,以下用法说明会似曾相识。

1    从http://sslext.sourceforge.net 下载ssl-ext 包。该包包含一个可工作的样例应用程序。把下载包Unzip 到Tomcat webapps 目录。在以下步骤中,你要从样例应用程序复制许多文件来创建你自己的ssl-ext 应用程序。

2    把sslext.jar 文件从样例应用程序复制到WEB-INF/lib 目录中。

3    把sslext.tld 文件从样例应用程序复制到你的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>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<!-- 配置ssl的tld --> <jsp-config>
     <taglib>
    <taglib-uri>/WEB-INF/sslext.tld</taglib-uri>
        <taglib-location>/WEB-INF/sslext.tld</taglib-location>
</taglib>
</jsp-config>

5    把插件标签添加到struts-config.xml 文件中。特别记下httpsPort 属性。它必须与用来配置Tomcat 的相同(步骤1,说明3)。如你可能预期的,该httpPort 属性应该和在conf/server.xml 中找到的Tomcat 配置相配。下列两个定义的值是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>

做完这些,你随时可以开始使用ssl-ext了。

步骤3:使用ssl-ext 建立一个应用程序

我们通过建立一个应用程序来示范ssl-ext 运转。在这个步骤中,我们展示ssl-ext 是如何被用来为指向ssl 安全页面的链接格式化URL 的。相反的,我们示范为指向普通的非SSL页面的链接格式化URL。我们将知道给页面提供安全保障是通过对struts-config.xml 做一个小的改变完成的。清单7.6 展示struts-config.xml 对应一个示例应用程序的动作映射。

清单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.apache.org/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 使一个Action 安全,把一个<set-property>标签嵌套在Action 标签内。 该property 属性的值永远是secure。该值属性的true 值表明我们需要URL通过设置URI 方案“https”来发出一个SSL 请求。类似的,false 值表明该页面是普通的不安全的页面;该URI 方案应该是“http”。一个any 值默认表示采用当前页的方案。虽然你可以使

用一个普通的Struts 链接标签达到相同效果,但是该any 值让你可以通过修改Struts-config 文件把它改成true 或者false 。

因为该安全属性不被默认动作映射支持,我们需要在(处)重载它。清单7.7示范ssl-ext 链接标签如何被用来产生一个协议格式的URL 。

清单7.7 menu.jsp: JSP 使用 ssl-ext 链接标签

<%@ 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>

指向安全页面的链接前缀https ,指向不安全的的页面的链接被格式化成通常的http 。例如,在处的链接显示为“不安全的”http://127.0.0.1:8080/ssl/unsecured.do,而在处的链接显示为“安全的”https://127.0.0.1:8443/ssl/secured.do。

在清单7.7中最显著的结果是我们从未指定页面使用SSL,是否是安全的。该信息是定义在struts-configxml 文件中的。在清单7.7中处的链接标签映射到清单7.6的处。相似的,处映射到处,处映射到处,处映射到处。当写URL 的协议段的时候,该ssl:ext 链接标签查阅struts-config.xml 文件。要使用该ssl-ext taglib,你需要像我们在处已经做的那样声明它。

提交工作以大体上相同的方式进行,只是你必须从ssl-ext 名字空间(处)(处)使用表单标签。

到这里,应用ssl-ext 的过程在上述步骤中得到完全解决。

◆ 讨论

因为步骤1和步骤2是显而易见的,我们无需回顾那些部分。步骤3更有意思得多,并且值得仔细考察。JSP 的工作很简单,不考虑sslext 名字空间的话,它看起来几乎无异于任何Struts JSP 。代替用Struts 链接标签写链接的是我们使用sslext 名字空间当中相同的标签。在这些场景后面,这些标签是使用动作映射来把URI 方案设置为http 或者https 的。要用https 写URL,把动作映射上的secure 属性设置为true。要把URL 写成“http”,把它设置为false。提交的过程也是一样,只是你使用sslext 名字空间的表单标签而不是Struts 的html 名字空间。

还有一个标签我们尚未讨论过。pageScheme标签使用secure属性 来强制一个到http 或者https 的重定向。例如,一个到<sslext:pageScheme secure="false">的页面的https 请求重定向该请求到http,而不管实际上该请求是用https发起的。

如果没有ssl-ext,用以保证URL 使用正确前缀方案的工作将会更加困难。代替通过在JSP 中修整每个ssl 链接来处理这个问题的是,我们可以从struts-conf. xml 文件中来管理它。如此,维护性方面的报偿是很客观的。例如,如果我们有到相同Struts Action 的20个链接,那么为了改变链接以使用SSL,必须对20个JSP 做改变。同等的改变在ssl-ext 下只需要对struts-config.xml的仅仅一个改动!犯太多罪过的是人,避免错误的是神。

最优方法

审慎地使用SSL——SSL 是一个认证和使应用程序安全的已被证实的、可靠的、灵活的,并且流行的办法,但是你应该仅当需要时才使用它。所有SSL 的传送都加密并解密数据。取决于选择的密码,这些运算会影响应用程序的性能。

◆ 参考

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


文章来源:http://x-spirit.spaces.live.com/Blog/cns!CC0B04AE126337C0!791.entry