安装及配置SSL支持
什么是安全套接字层技术?
安全套接字层(SSL)是允许Web浏览器和Web服务通过安全连接进行通信的技术。在这种安全连接上,数据在发送前经过加密码,然后在接收时先解密再进行处理。浏览器和服务器在发送任何数据之前都对所有流量加密。SSL是针对下列重要的安全性考虑的:
身份验证
在第一次尝试与Web服务器通过安全连接通信时,这台服务器将以服务器证书的形式向Web浏览器发送一份凭证。这个证书的目的是验证这个站点就是它所宣称的那一个。在有些情况下,服务器可能要求客户端提供证明它就是它所宣称的身份的证书(即客户端身份验证)。
机密性
数据通过网络在客户端与服务器之间传送时,第三方可以查看并截获该数据。SSL响应是加密的,这样数据就不会被第三方解密而仍然保持其机密机。
完整性
当数据通过网络在客户端与服务器之间传送时,第三方可以查看并截获该数据。SSL帮助保证数据在传输过程中不被第三方修改。
要在自己的独立Web服务器上安装并配置SSL,需要下列组件。以下各节专门讨论在Tomcat上启用SSL支持。如果使用不同的Web服务器,请参照相应产品的文档。
· Java 安全套接字扩展(Java Secure Socket Extension JSSE))(见使用JSSE)。
· 服务器证书keystore(见设置数字证书)。
· 一个HTTPS连接器(见配置SSL连接器)。
要验证启用了SSL支持,参见验证SSL支持。
使用JSSE
如果使用J2SE SDK v1.3.1,那么需要安装Java安全套接字扩展(JSSE)以使用SSL。JSSE是J2SE 1.4 SDK的一部分。JSSE是一组Java包,它使安全Internet通信成为可能。这些包实现了Java版本的SSL(安全套接字层)和TLS(传输层安全性)协议并包括数据加密、服务器身份验证、消息完整性和可选的客户端验证功能。使用JSSE,开发者在可以为客户端和运行任何TCP/IP之上的应用协议(如HTTP、Telnet、NNTP和FTP)的服务器之间提供安全数据传输。
在默认情况下,jsse.jar文件的位置是<JAVA_HOME>/jre/lib/jsse.jar。有关JSSE的更多信息,参见其Web站点http://java.sun.com/products/jsse/。
设置数据证书
为了实现SSL,一个Web服务必须对每一个接受安全连接的外部接口或者IP地址有一个相关联的证书。这种设计背后的理论是服务器应该对其拥有者身份提供某种合理的保证,特别是在接收任何敏感信息之前。将证书想像为Internet地址的“数字驱动的许可许”可能会有帮助。它声明这个站点与哪个公司相关联,以及站点所有者或者管理员的一些基本联系信息。
数字证书是由其拥有者加密签名,任何其他人都难以仿造。对于涉及电子商务的站点,或者任何其他身份验证起重要作用的业务交易站点,可以从像verisign或者Thawte这样的著名证书颁发机构(Certificate Authority CA)购买证书。
如果身份验证并不很重要,比如管理员只是希望保证服务器发送和接收的数据是私有的并且不能被连接中的任何窃听者探听到,则可以只是使用自签名的证书,从而省去获取CA证书的时间和成本。
SSL使用公钥加密,它基于密钥对。密钥对包含一个公钥和一个私钥。如果数据是用其中一把钥匙加密的,那么只能用钥匙对中的另一把钥匙解密。这种特性是建立交易信任和私有性的基础。例如,使用SSL时,服务器计算出一个值并用其私钥加密这个值。加密的值称为数字签名。客户端用服务器的公钥解密这个加密的值并将这个值与它自己的计算值进行比较。如果这两个值相匹配,那么客户端就可以信任签名是真的,因为只有用私钥才可以生成这个签名。
数字证书与HTTPS协议一共使用以验证Web客户端身份。除非安装了数字证书,否则大多数Web服务的HTTPS服务都不会运行。使用下面描述的过程设置可以被Web服务器使用的数字证书以启用SSL。
一种可以用于设置数字证书的工具是keytool,这是一种与J2SE 1.4 SDK一同发布的密钥和证书管理工具。它使用户可以管理他们自己的公/私钥对以及相关的证书,以在自验证(用户向其他用户/服务验证他/她自己)或者数字完整性和身份验证服务用使用。它还让用户可以缓存他们通信伙伴的公钥(以证书的形式)。要更好地理解公钥加密,参阅以下地址上的文档
http://java.sun.com/j2se/1.4.1/docs/tooldocs/solaris/keytool.html
证书是来自某一实体(人员、公司等)的数字签名的声明,表明其他实体的公钥(或者一些其他信息)有一个特定值。当对数据进行数字签名后,可以对该签名进行验证以检查数字完整性和真实性。完整性意味着数据没有被修改或者篡改,真实性意味着数据确实是来自宣称创建和对它签名的地方。
keytool将储存密钥和证书储存在一个名为keystore的文件中。Keystore的默认实现将keystore实现为一个文件。它用密码保护私钥。有关keytool的更多信息,参阅以下地址的文档
http://java.sun.com/j2se/1.4.1/docs/tooldocs/solaris/keytool.html
本节描述创建一个名为server.keystore的服务器keystore以及名为client.keystore的客户端keystore。这两个文件构成一个密钥对。这些文件通常是在<HOME>目录中或者在应用程序目录中创建的。
除了服务器和客户端keystore,还必须有签名的证书,它必须存在于服务器上。在服务器验证客户端身份时,这个文件必须包含证书颁发机构的公钥证书或者客户端的公钥证书。我们将在<HOME>目录中创建server.cer。
通常,keystore文件是由密码保护的。对于server.keystore、client.keystore和server.cer文件这个密码的默认值是changeit。
我们使用keytool工具创建keystore文件。可以在<JAVA_HOME>/bin目录中找到keytool工具。
要设置数字证书,
1. 生成密钥对
keytool工具使您可以生成密钥对。随J2SE SDK发布的keytool工具在程序中增加了实现了RSA算法的Java 密码扩展提供程序。这个提供程序使您可以导入RSA签名的证书。
如下运行keytool工具以生成keystore文件,用keystore文件的名字替换<keystore_filename>,例如server.keystore。如果使用Tomcat服务器,文件必须命名为.keystore并位于Tomcat运行的计算机的home目录中,或者通过在Tomcat配置文件中的<Factory>元素中添加一个keystoreFile属性、或者在admintool的Connector (8443)节点上指定该文件的位置以告诉Tomcat这个keystore文件是什么地方。
keytool -genkey -keyalg RSA -alias tomcat-server
-keystore <keystore_filename>
2. keytool工具提示您加入以下信息:
a. Keystore password--输入默认密码,即changeit。有关改变密码的信息参见keytool文档。
b. First and last name——输入适当的值,例如JWSDP。
c. Organizational unit——输入适当的值,例如Java Web Services。
d. Organization——输入适当的值,如Sun Microsystems。
e. City or locality——输入适当的值,例如Santa Clara。
f. State or province——.输入非缩写名,如CA。
g. Two-letter country code-——对于美国,双字母国家代码是US。
h. Review the information you've entered so far, enter Yes if it is correct.检查输入的信息,如果都正确,则输入Yes。
i. Key password for the Web server——不输入密码。按回车。
下一步是为该keystore生成签名的证书。一个自签名的证书对于大多数SSL通信来说是可以接受的。如果使用自签名的证书,则进入创建自签名的证书。如果想让证书由CA数字签名,则进入获取数字签名的证书。
创建自签名的证书
本例假设keystore命名为server.keystore,证书文件是server.cer,CA文件是cacerts.jks。在<HOME>目录中运行以下命令以使它们创建到这里。
1. 将服务器证书导出为证书文件:
keytool -keystore server.keystore -export -alias tomcat-server -file server.cer
2. 输入密码(changeit):
Keytool返回下列消息:
Certificate stored in file <server.cer>
3. 将新的服务器证书导入到证书颁发机构文件cacerts.jks:
keytool -import -alias serverCA -keystore <HOME>/cacerts.jks
-file server.cer
4. 输入密码(changeit)。
Keytool返回类似下面的消息:
Owner: CN=JWSDP, OU=Java Web Services, O=Sun, L=Santa Clara,
ST=CA, C=US
Issuer: CN=JWSDP, OU=Java Web Services, O=Sun, L=Santa Clara,
ST=CA, C=US
Serial number: 3e39e3e0
Valid from: Thu Jan 30 18:48:00 PST 2003 until: Wed Apr 30 19:48:00 PDT 2003
Certificate fingerprints:
MD5: 44:89:AF:54:FE:79:66:DB:0D:BE:DC:15:A9:B6:09:84
SHA1:21:09:8A:F6:78:E5:C2:19:D5:FF:CB:DB:AB:78:9B:98:8D:06:8C:71
Trust this certificate? [no]: yes
Certificate was added to keystore
获取数字签名的证书
本例假设keystore命名为server.keystore,证书文件为server.cer,并且CA文件是cacerts.jks。
1. CA获得数字签名的证书。为此,
a. 生成证书签名请求(Certificate Signing Request CSR)。
keytool -certreq -alias tomcat-server -keyalg RSA
-file <csr_filename> -keystore cacerts.jks
b. 发送csr_filename的内容以进行签名。
c. 如果使用Verisign CA,则进入http://digitalid.verisign.com/。Verisign将在电子邮件中发送签名的证书。将这个证书储存在一个文件中。
d. 将通过电子邮件收到的签字的证书导入服务器:
keytool -import -alias tomcat-server -trustcacerts -file
<signed_cert_file> -keystore <keystore_filename>
2. 导入证书(如果使用CA签名的证书)。
如果证书是由证书颁发机构(CA)签名,那么必须导入CA证书。如果只使用自签名证书则可跳过这一步。如果使用自签名证书或者由浏览器不识别的CA签名的证书,那么用户第一次试图访问服务器时就会跳出一个对话框。用户可以选择只在这个会话中、还是永远信任这个证书。
要在标准版本的Java 2平台安装CA证书,如下运行keytool工具。
keytool -import -trustcacerts -alias root
-file <ca-cert-filename> -keystore <keystore-filename>
为相互验证创建客户端证书
创建客户端证书的过程与创建服务器证书类似。
1. 用keytool在所选的keystore文件中创建客户端证书:
keytool -genkey -keyalg RSA -alias jwsdp-client -keystore client.keystore
会提示输入密码。输入默认密码changeit。根据提示输入名字、组织和其他客户端信息。不要在“Key password for <client>”输入任何内容,只需要按回车。
2. 将新客户端证书从keystore导出到证书文件:
keytool -keystore client.keystore -export -alias jwsdp-client -file client.cer
3. 输入keystore密码(changeit)。Keytool将返回该消息:
Certificate stored in file <client.cer>
4. 将新客户端证书导入到服务器的证书颁发机构文件cacerts.jks中。这使服务器在SSL相互验证过程中信任该客户端。
keytool -import -alias root -keystore <HOME>/cacerts.jks
-file client.cer
5. 输入keystore密码(changeit)。Keytool返回下面的消息:
Owner: CN=JWSDP Client, OU=Java Web Services, O=Sun, L=Santa
Clara, ST=CA, C=US
Issuer: CN=JWSDP Client, OU=Java Web Services, O=Sun, L=Santa Clara, ST=CA, C=US
Serial number: 3e39e66a
Valid from: Thu Jan 30 18:58:50 PST 2003 until: Wed Apr 30
19:58:50 PDT 2003
Certificate fingerprints:
MD5: 5A:B0:4C:88:4E:F8:EF:E9:E5:8B:53:BD:D0:AA:8E:5A
SHA1:90:00:36:5B:E0:A7:A2:BD:67:DB:EA:37:B9:61:3E:26:B3:89:46:
32
Trust this certificate? [no]: yes
Certificate was added to keystore
检查相互验证是否已运行
要证明SSL握手已进行,关闭Tomcat,在<JWSDP_HOME>/bin/catalina.bat文件中发送debug旗标,然后重新启动Tomcat。服务将显示握手消息,或者将它们写入文件<JWSDP_HOME>/logs/launcher.server.log中。下面例子以粗体显示新代码。
rem Execute the Tomcat launcher
"%JAVA_HOME%\bin\java.exe" -Djavax.net.debug=ssl,handshake
-classpath %PRG%\..;%PRG%\..\..\jwsdp-shared\bin;"%PRG%
在Tomcat服务器使用PKCS12证书
Java WSDP支持PKCS12格式的证书。PKCS12标准规定储存或者传输用户私钥、证书和各种秘密的可移植格式。更多信息参见以下Web站点:
http://www.rsasecurity.com/rsalabs/pkcs/pkcs-12
如果有PKCS12格式的证书,那么必须将它转换为JKS格式。进行转换的命令是:
keytool -pkcs12 -pkcsFile <fileName> -pkcsKeyStorePass
<password> -pkcsKeyPass <password> -jksFile <outputFileName>
-jksKeyStorePass <password>
结果是一个含有密钥——私钥和证书链——的JKS文件。
用带-export选项的keytool将证书导出到一个文件中,如abc.cer:
keytool -keystore <outputFileName> -export -alias <server> -file abc.cer
证书的各种命令
· 检查服务器证书的内容:
keytool -list -keystore server.keystore -alias tomcat-server -v
· 检查cacerts文件的内容:
keytool -list -keystore cacerts.jks
配置SSL连接器
取决于Web服务器,可能它会启用SSL HTTPS连接器,也可能不启用。如果使用Tomcat服务器,那么就没有配置SSL连接器。本节描述如何为Tomcat配置SSL HTTPS连接器。如果使用其他Web服务器,则应该参考相应服务器的文档。
在部署描述符中必须包含一个用于SSL连接的元素Connector。在改变服务器部署描述符之前,必须关闭服务器。下列代码是在Web服务器上启用SSL连接器的代码示例:
<Connector
className="org.apache.coyote.tomcat5.CoyoteConnector"
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="true" acceptCount="10" debug="0"
scheme="https" secure="true" useURIValidationHack="false">
<Factory className="com.sun.web.security.SSLSocketFactory"
clientAuth="false" protocol="TLS" debug="0" />
</Connector>
这个Connector元素的属性在附录A Tomcat服务器管理工具中有更详细的描述。可以使用下面两种方法之一向Tomcat添加SSL HTTPS连接器:
· 使用admintool添加Connector。参见在admintool中添加SSL连接器。
· 向服务器的部署描述符添加SSL连接器的Connector元素。参见在server.xml中配置SSL。
在admintool中添加SSL连接器
要用admintool配置SSL连接器,必须首先像在设置数字证书中所描述的那样创建一个keystore。Tomcat会在它所运行的计算机上的主目录中寻找名为.keystore的keystore。确认已经创建了keystore以后,进行以下步骤:
1. 如果Tomcat还没有启动,就启动它。
2. 在Web浏览器中输入http://localhost:8080/admin in a Web browser启动admintool。
3. 输入为admin角色指定的用户名和密码组合。
4. 在左边窗格中选择服务(Java Web Services Developer Pack)。
5. 从右边窗格中的下拉列表中选择Create New Connector。
6. 在Type域,选择HTTPS。
7. 在Port域,输入8443(或者其他所要求的端口)。这会定义Tomcat会监听哪个安全连接的TCP.IP端口号。
8. 如果创建了keystore,其名字不是.keystore,如果keystore不在Tomcat所运行的计算机上的home目录中,或者密码不是默认值changeit,则输入Keystore Name和keystore Password。如果使用了期望值,则可以不填写这些域。
在Unix和Linux系统中home目录是/home/user_name,在Microsoft Windows系统中是C:\Documents and Settings\user_name。
9. 选择Save以为该会话保存新Connector。
10. 选择Commit Changes以将新Connector信息写入文件server.xml,这样下次Tomat启动时它就是可用的了。
要查看和/或者编辑新创建的Connector,展开Service(Java Web Services Developer Pack)节点,并选择Connector(8443)。
在server.xml中配置SSL Connector
在默认server.xml中包括了一个SSL Connector的示例Connector元素。在默认情况下这个Connector元素是注释掉的。要为Tomcat启用SSL Connector,去掉围绕着SSL Connector元素的注释标记。为此,执行以下步骤。
1. 如果Tomcat正在运行,则关闭它。当Tomcat再次启动时对<JWSDP_HOME>/conf/server.xml文件的修改就可被它使用了。
2. 在文本编辑器中打开文件<JWSDP_HOME>/conf/server.xml。
3. 在文件中找到下代码部分(可以试着搜索SSL Connector)。删除围绕Connector项的注释。要删除的注释标签以粗体表示。
<!-- SSL Connector on Port 8443 -->
<!--
<Connector
className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8443" minProcessors="5"
maxProcessors="75"
enableLookups="false"
acceptCount="10"
connectionTimeout="60000" debug="0"
scheme="https" secure="true">
<Factory
className="org.apache.coyote.tomcat4.
CoyoteServerSocketFactory"
clientAuth="false" protocol="TLS" />
</Connector>
-->
4. 保存并关闭文件。
5. 启动Tomcat。
在Tomcat管理工具文档中对这个Connector元素中的属性有更详细的描述。
验证SSL支持
为了进行测试,并验证SSL支持已经正确安装,用连接到在服务器部署描述符中定义的端口的URL装载默认的介绍页面:
https://localhost:8443/
这个URL中的https表明浏览器应该使用SSL协议。端口8443就是在前面一步中创建SSL Connector的端口
用户第一次装载这个应用程序时,会显示New Site Certificate对话框。选择Next通过一系列New Site Certificate对话框,到达最后一个对话框时,选择Finish。
有关运行SSL的一般性提示
SSL协议设计为尽可能地高效和安全。不过,从性能的角度看,加密/解密是一种需要大量计算的过程。不一定要将整个Web应用都放到SSL上,并且一般由开发者决定哪一页面需要安全连接,哪一页面不需要。可能需要安全连接的页面包括登录页面、个人信息页面、购物小车付款、或者任何其他可能传送信用卡号的页面。可以仅通过加在地址上用https个取代http前缀而使应用程序中的任何一页面运行在安全套接字上。对任何绝对要求安全连接的页面都应该检查与该页面请求相关联的协议类型,如果没有指定https就要采取相应措施。
使用在安全连接上的基于名字的虚拟主机可能会有问题。这是SSL协议本身的一个设计局限。SSL握手必须在访问HTTP请求之前发生,在握手时客户端浏览器接受服务器证书。结果,不能在身份验证之前确定包含虚拟主机名的请求信息,并且因此不可能对一个IP地址指定多个证书。如果在一个IP地址上的所有虚拟主机需要针对同一个证书进行验证,那么额外的多个虚拟主机就不应该介入服务器上的普通SSL操作。不过要知道,大多数客户端浏览器会比较服务器的域名和在证书中列出的域名,如果有列出的话(主要适用于正式的、CA签名的证书)。如果域名不匹配,那么这些浏览器将向客户端显示一个警告。一般来说,在生产环境中只有基于地址的虚拟主机通常会使用SSL。
SSL连接的故障排除
启动Tomcat时,得到这样的异常“"java.io.FileNotFoundException: {some-directory}/{some-file} not found”
一个可能的解释是Tomcat不能找到它要寻找的keystore文件。在默认情况下,Tomcat期待keystore命名为.keystore,并且位于Tomcat所在的系统中的home目录(与您自己的计算机上的home目录可能一致、也可能不一致) 。如果keystore文件是在其他位置,那么就需要在Tomcat配置文件中的<Factory>元素上添加一个keystoreFile属性,或者在admintool的Connector (8443)节点指定文件的位置。
Tomcat启动时,得到这样的异常“"java.io.FileNotFoundException: Keystore was tampered with, or password was incorrect”。
假设没有人改变了您的keystore文件,最有可能的原因是Tomcat使用了与创建keystore文件时使用的不同的密码。要解决这个问题,可以返回并重新创建keystore文件,也可以在Tomcat配置文件中的<Factory>元素上、或者在的Connector (8443)节点上添加keystorePass属性——提醒--密码是大小写敏感的。
如果仍然有问题,
如果仍然有问题,邮件列表是一个好的信息资源。可以在http://jakarta.apache.org/site/mail.html上查看这个列表中以前的消息,还可以预订和取消预订信息。
有关SSL的进一步信息
更多信息请参阅<JWSDP_HOME>/docs/tomcat/ssl-howto.html上的Tomcat文档SSL Configuration HOW-TO。
JAX-RPC的安全性
在本节,将学习如何配置基于JAX-RPC的Web服务应用程序以进行HTTP/SSL上的基本和相互身份验证。如果验证对于您来说还是一个新题目,那么请参见验证Web资源的用户那一节。
在本教程中,我们要修改<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hello中的示例应用程序以添加HTTP/S基本和相互身份验证。可以在目录<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security中找到所得到的应用程序。下列步骤是向hello例子中添加基本验证的必要步骤:
· 创建相应的证书和keystore(参见第1步:为基本身份验证创建SSL证书)。
· 确保为服务器配置了SSL 连接器。Tomcat服务器没有配置SSL Connector,所以需要添加SSL Connector(参见配置SSL连接器)并在生成的keystore文件中添加信息(见第2步:配置SSL 连接器)。
· .向部署描述符web.xml添加安全元素。有关操作信息参见第3步:向web.xml添加安全元素。
· 在应用程序的build.properties文件中修改端点地址,并添加运行这个例子所需要的其他属性。参见第4步:编辑Build属性。
· 在客户端代码中设置安全属性。有关操作信息参见第5步:在客户端代码中设置安全属性。
· 编译并运行Web服务。有关对示例应用程序完成这项操作的信息见第6步:创建NewAnt Target以运行这个例子。
在这里描述为Web服务配置HTTP/S上的基本身份验证的步骤。对于相互身份验证,完成下述步骤,再按启用SSL上的相互验证中的说明添加客户端验证。
第1步:为基本身份验证创建SSL证书
注:在设置数字证书中对这些信息有更详细的讨论。本节总结了为这个例子创建SSL证书所需要的步骤。
我们将用工具keytool生成SSL证书并将它们导出为相应的服务器和客户端keystore。记住服务器和客户端keystore是在运行keytool的目录中创建的。因为我们是向hello Web服务添加安全性,所以我们从修改的示例应用程序所在目录中运行keytool,这就是<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security目录。这样,keystore就在security Web服务的代码所在的同一目录中生成。
1. 运行keytool以生成服务器和客户端keystore。对于基本身份验证,只需要将服务器证书导入到客户端keystore。用默认密码changeit生成服务器keystore。
要生成服务keystore,在终端窗口输入下面内容。在继续之前确是在<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security目录中。
注意在按Enter时,keytool提示您输入服务器名、组织单位、组织、所在地、州和国家代码。注意必须在keytool的要求输入姓和名的第一个提示中输入服务器名。为了进行测试,可以用localhost。这个主机必须与在第4步:编辑Build属性中指定的端点地址中标识的主机相匹配。
<J2SE_HOME>\bin\keytool -genkey
-alias tomcat-server
-keyalg RSA -keypass changeit
-storepass changeit
-keystore server.keystore
2. 导出生成的服务器证书。
<J2SE_HOME>\bin\keytool -export -alias tomcat-server
-storepass changeit -file server.cer -keystore
server.keystore
3. 生成客户端keystore。
要生成客户端keystore,在终端窗口中输入以下内容:
注意在按Enter时,keytool提示您输入客户端的服务器名、组织单位、组织、所在地、州和国家代码。注意必须在keytool的要求输入姓和名的第一个提示中输入服务器名。在大多数情况下,为了进行测试,可以使用localhost。这个主机必须与在第4步:编辑Build属性中指定的端点地址中标识的主机相匹配。
<J2SE_HOME>\bin\keytool -genkey -alias jwsdp-client -keyalg
RSA -keypass changeit -storepass changeit -keystore
client.keystore
4. 将服务器证书导入客户端的keystore。
<J2SE_HOME>\bin\keytool -import -v -trustcacerts
-alias tomcat-server -file server.cer
-keystore client.keystore -keypass changeit
-storepass changeit
第2步:配置SSL连接器
注:在配置SSL 连接器一节中更详细地提供了配置SSL 连接器的步骤。本节中的步骤是为了您的方便提供的。
需要为Tomcat配置一个SSL Connector。如果使用不同的服务器,参见配置SSL 连接器中配置SSL Connector的一般信息。除了为服务配置一个SSL 连接器外,还必须在添加SSL连接器的同一位置上添加有关keystore文件的信息及其密码。例如,在Java WSDP中,首先需要从SSL Connector周围删除注释标签(<!-- ... -->),然后在<JWSDP_HOME>/conf/server.xml文件中的这一部分添加以粗体显示的信息。
<!-- SSL Connector on Port 8443 -->
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="false"
acceptCount="10" debug="0" scheme="https" secure="true">
<Factory className= "org.apache.coyote.tomcat4.CoyoteServerSocketFactory">
keystoreFile=
"<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security/ server.keystore"
keystorePass="changeit"
clientAuth="false" protocol="TLS" debug="0" />
</Connector>
第3步:向web.xml添加安全元素
这个例子的文件在<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security目录中。要通过SSL进行身份验证,web.xml文件包括<security-constraint>、 <login-config>,和<security-role>元素。在基本<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hello例子之上添加了粗体的代码。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application
2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">
<web-app>
<display-name>Hello World Application (secure)</display-name>
<description>HTTPS example using JAX-RPC </description>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<security-constraint>
<web-resource-collection>
<web-resource-name>SecureHello</web-resource-name>
<url-pattern>/security</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>manager</role-name>
</security-role>
</web-app>
注意<role-name>元素指定了manager,这是一个已经在Tomcat的部署描述符(<JWSDP_HOME>/conf/tomcat-users.xml)中指定的角色。有关角色定义和链接的更多内容,参见安全性角色。
第4步:编辑Build属性
要以HTTP/SSL上的基本身份验证运行这个应用程序,我们向build.properties文件添加与keystore文件相关的一些属性及其密码,这个文件位于<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security目录中。下述例子假设运行的是Java WSDP 1.1。以粗体标记的项被添加到文件中。在后面一节中运行它时,所添加的项将作为参数传递给客户端应用程序。
# This file is referenced by the build.xml file.
example=security
context-path=security-jaxrpc
client-class=security.HelloClient
client-jar=${example}-client.jar
portable-war=${example}-portable.war
deployable-war=${context-path}.war war-path=${tut- root}/tutorial/examples/jaxrpc/${example}/dist/${deployable- war}
trust-store=${tut-root}/tutorial/examples/jaxrpc/security/cli-
ent.keystore
trust-store-password=changeit
第5步:在客户端代码中设置安全属性
客户端的源代码在<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security目录中的HelloClient.java文件中。对于SSL上的基本身份验证,客户端代码必须设置几项安全相关的属性。
· trust-store属性——trust-store属性的值是客户端 keystore文件的完全限定名:<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security/client.keystore
· trust-store-password属性——trust-store-password属性是keystore的密码。这个密码的默认值是changeit。
· username和 password属性——username和password属性对应于manager角色(见安全性角色)。
客户端如下设置前述的安全属性。粗体的代码是在原来的jaxrpc/hello示例应用程序上添加的代码。
package security; import javax.xml.rpc.Stub;
public class HelloClient {
public static void main(String[] args) {
if (args.length !=4) {
System.out.println("Usage: ant run-security"); System.exit(1); }
String trustStore=args[0];
String trustStorePassword=args[1]; String username=args[2]; String password=args[3];
System.out.println("trustStore: " + trustStore); System.out.println("trustStorePassword: " +
trustStorePassword);
System.out.println("username: " + username);
System.out.println("password: " + password);
try {
Stub stub = createProxy();
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
stub._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY,
username);
stub._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, password);
HelloIF hello = (HelloIF)stub;
System.out.println(hello.sayHello("Duke! I feel
secure!"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static Stub createProxy() {
// Note: MyHelloService_Impl is implementation-specific.
return (Stub)(new MyHello_Impl().getHelloIFPort());
}
}
第6 步:创建New Ant Target以运行这个例子
运行hello示例应用程序的现有目标还不足以运行运行安全版本的应用程序。需要传递关于keystore及其密码的信息,以及用户名及用户密码。下列targe添加到<JWSDP_HOME>/docs/examples/jaxrpc/security/build.xml文件中,以便于运行安全的JAX-RPC例子:
<target name="run-security"
description="Runs a client with authentication
over ssl">
<echo message="Running the ${client-class} program...." />
<java
fork="on"
classpath="${dist}/${client-jar}:${jwsdp-jars}"
classname="${client-class}" >
<arg value="${trust-store}" />
<arg value="${trust-store-password}" />
<arg value="${username}" />
<arg value="${password}" />
</java>
</target>
第7步:编译并运行这个例子
要编译并在SSL上运行这个JAX-RPC例子,执行以下步骤:
1. 如果没有做的话,按照设置中的指示,下载本教程的示例代码,完成上述第1到2步,因为这些步骤是对您的计算机和实现特定的。
2. 确保Tomcat正在运行。
3. 进入<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security目录。
4. 键入下述命令:
ant build
ant package
ant deploy
ant build-static
ant run-security
客户端应该显示下述输出:
% ant run-security
Buildfile: build.xml
run-security:
[echo] Running the security.HelloClient program...
[java] trustStore: <JWSDP_HOME>/docs/tutorial/examples/
jaxrpc/security/client.keystore
[java] trustStorePassword: changeit
[java] username: your_name
[java] password: your_password
[java] Hello - secure Duke! I feel secure!
BUILD SUCCESSFUL
启用SSL上的相互身份验证
TJAX-RPC安全性一节对设置服务器端身份验证进行了讨论。本节讨论设置客户端身份验证。当服务器和客户端身份验证都启用时,这称为相互、或者双向验证。在客户端身份验证中,客户端需要提交由你所选择的可以接受的证书颁发机构颁发的证书。至少有两种途径启用客户端身份验证。
1. .配置SSL套接字工厂启用客户端验证。例如,要为Tomcat配置SSL套接字工厂 ,要设置clientAuth="true",如下面代码示例中的粗体部分。以这种方式启用客户端验证,对于所有通过特定SSL端口进入的请求都会要求客户端验证。与对Web服务配置文件所做的所有改变一样,必须停止并重新启动Web服务以使这种改变生效。
<!-- SSL Connector on Port 8443 -->
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="false"
acceptCount="10" debug="0" scheme="https" secure="true">
<Factory className=
"org.apache.coyote.tomcat4.CoyoteServerSocketFactory">
keystoreFile=
"<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/security/
server.keystore"
keystorePass="changeit"
clientAuth="true" protocol="TLS" debug="0" />
</Connector>
2. 如下面粗体部分所示。以这种方法启用客户端身份验证,客户端身份验证是对特定的应用程序启用的。
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
3. 如果同时用上述两种方法启用客户端身份验证,那么客户端身份验证将会执行两次。
为JAX-RPC安全示例配置相互验证
要以相互验证配置并创建JAX-PRC服务,执行JAX-RPC安全性中的所有步骤,直到ant build-static命令 (包括这一步)。然后执行以下步骤:
1. 生成客户端证书,导出它,再将客户端证书导入服务器keystore,如为相互验证创建客户端证书中所讨论的。
2. 编辑web.xml以将部署描述符中的登录配置部分的身份验证方法改为CLIENT-CERT。
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
3. :运行这个应用程序:
ant run-security
客户端应该显示以下一行:
Hello Duke! I feel secure!
致谢:本节包括由Rahul Sharma和Beth Stearns编写的“Web Services Security Configuration”白皮书中的内容。
EIS层安全性
在EIS层,应用程序组件请求到EIS资源的连接。作为这种连接的一部分,EIS可能请求对资源的sign-on。应用程序组件提供者有两设计这种EIS sign-on的选择:
· 使用容器托管的sign-on方式,应用程序组件让容器负责配置并管理EIS sign-on。容器确定用户名和密码以建立到EIS实例的连接。
· 用组件托管的sign-on方式,应用程序组件代码通过加入执行sign-on过程的代码管理EIS sign-on。
容器托管的登录(Sign-On)
使用容器托管的登录,应用程序组件不必为了登录资源而向getConnection()方法传递任何安全信息。安全信息是由容器提供的,如下面的例子所示。
// Business method in an application
component Context initctx = new InitialContext();
// Perform JNDI lookup to obtain a connection factory javax.resource.cci.ConnectionFactory cxf =
(javax.resource.cci.ConnectionFactory)initctx.lookup(
"java:comp/env/eis/MainframeCxFactory");
// Invoke factory to obtain a connection. The security
// information is not passed in the getConnection method
javax.resource.cci.Connection cx = cxf.getConnection();
...
组件托管的登录
使用组件管理的登录,应用程序组件负责向getConnection()方法传递登录资源所需要的安全信息。安全信息可以是用户名和密码,如下例所示:
// Method in an application
component Context initctx = new InitialContext();
// Perform JNDI lookup to obtain a connection factory javax.resource.cci.ConnectionFactory cxf =
(javax.resource.cci.ConnectionFactory)initctx.lookup(
"java:comp/env/eis/MainframeCxFactory");
// Get a new ConnectionSpec
com.myeis.ConnectionSpecImpl properties = //..
// Invoke factory to obtain a connection
properties.setUserName("...");
properties.setPassword("...");
javax.resource.cci.Connection cx =
cxf.getConnection(properties);
...