简介: ?随着 Web Service 应用越来越广泛, 如何保证服务能够安全的访问和传输,也逐渐引起开发人员和用户的关注。Web Service 的安全可以从两方面考虑:访问安全和传输安全 .。前者主要指只有授权用户可以访问应用, 而后者侧重于在消息传输过程中如何保证消息的私密性和完整性。本文介绍了如何在 Apache Geronimo 开发和部署安全的 Web Service 应用,以确保信息交互的安全,将侧重介绍如何基于 HTTP/HTTPS 协议保护 Web Service 应用访问和传输的安全。
?
Web Service Security 简介
在 Java EE 平台上,先后有了 JAX-RPC 和 JAX-WS 两个 Web Service 应用规范,但是两者均未对安全方面做详细规定。那么如何确保 Web Service 应用的安全呢?总所周知,Web Service 应用的服务端和客户端是使用 SOAP 作为交互协议,而 SOAP 作为一个应用层的协议,可以基于多种其他协议传输, 例如 HTTP/HTTPS,FTP 等。 而在实际的应用环境之中, HTTP/HTTPS 协议是应用最为广泛的 .。事实上, 在 SOAP 和 Web Service 的相关规范中, 主要对 SOAP 基于 HTTP/HTTPS 上进行传输作了说明。显然,当我们考虑 Web Service 安全时, 在传输协议进行安全控制便是一个自然而然的选择方案之一。
Apache Geronimo 中的 Web Service Provider
Apache Geronimo 共集成了三个比较流行的 Web Service 引擎, 分别是 Apache Axis, Apache Axis2 和 Apache CXF。 对于 Axis, 通过集成其实现对 JAX-RPC 规范的支持, 后续两个项目, 侧重提供对 JAX-WS 规范的支持。 在 Geronimo 的两个发行版本 Geronimo-Tomcat 和 Geronimo-Jetty 中, 分别默认启用了 Axis2 和 CXF。对于 Geronimo 的两个发行版本,用户可以通过安装对应插件并进行简单配置以切换至另外一种 Web Service 引擎, 详情请参照 Geronimo 的相关文档,,本文不再作累述。 默认情况下, 本文示例均是运行于 Geronimo-Tomcat 发行版本上,并使用 Axis2 作为 Web Service 引擎,并遵循 JAX-WS 规范编写。
一个简单的 Web Service 应用
本文中, 我们以一个在线书店的应用为例, 其提供通过书名检阅图书的功能, 并以 Web Service 的形式对外提供服务。同时还有一个 Web 客户端应用,来访问在线书店提供的服务。如 清单 1
所示,服务端是一个简单的 POJO 类,并添加了 WebService 标识。其提供 queryByName
的方法,以传入的 name
为参数检索是否有符合条件的书籍,最终返回一个 Book
对象数组。
清单 1. 在线书店服务端实现
@WebService(name = "BookStore", targetNamespace = "http://geronimo.apache.org/bookstore") public class BookStoreImpl { private List<Book> books = new LinkedList<Book>(); @PostConstruct protected void initialize() { books.add(new Book("1", "Thinking In Java", "Bruce")); books.add(new Book("2", "WAS CE Bible", "WAS CE Team")); } public Book[] queryByName(String name) { if (name == null || name.length() == 0) { return new Book[0]; } List<Book> foundBookList = new ArrayList<Book>(); for (Book book : books) { if (book.getName().indexOf(name) != -1) { foundBookList.add(book); } } return foundBookList.toArray(new Book[0]); } @PreDestroy protected void destory() { books.clear(); } } |
?
同时,在部署文件 web.xml 中,我们将 清单 1 中所示 POJO 类以 Servlet 形式对外发布,具体配置请参照 清单 2 。
清单 2. web.xml 配置片段
<servlet> <servlet-name>BookStore</servlet-name> <servlet-class> org.apache.geronimo.samples.securityWebService.BookStoreImpl </servlet-class> </servlet> <servlet-mapping> <servlet-name>BookStore</servlet-name> <url-pattern>/bookstore</url-pattern> </servlet-mapping> |
?
将以上所示的应用部署至 Apache Geronimo 中后,在浏览器输入 http://localhost:8080/SecurityWebServices/bookstore 后,如若 图片 1 所示,即表示该在线书店的应用已经成功部署了。
图片 1. BookStoreImplService 访问页面
Web Service 客户端
客户端同样是一个 Web 应用程序,首先通过工具根据 Geronimo 生成的 WSDL 文件生成本地的相关类文件, 通过在 BookStoreClient 中使用 WebServiceRef
标识注入的方式获取 BookStore 服务的引用, 请参照 清单 3
:
清单 3. 客户端代码片段
BookStoreClient.java @WebServiceRef(name = "services/BookStore") private BookStoreImplService service; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String queryName = request.getParameter("name"); if (queryName != null && queryName.length() > 0) { request.setAttribute("books", service.getPort(BookStore.class).queryByName(queryName)); } request.getRequestDispatcher("index.jsp").forward(request, response); } |
?
而在客户端应用的 web.xml 和 geronimo-web.xml 文件中, 需要配置该服务的一些参数, 请参照 清单 4 。设置参数主要包括服务端 Web Service 的发布地址等信息,对应于 清单 2 中的配置。
清单 4. web.xml/geronimo-web.xml 配置片段
web.xml <service-ref> <service-ref-name>services/BookStore</service-ref-name> <service-interface> org.apache.geronimo.samples.securityWebService.BookStoreImplService </service-interface> </service-ref> geronimo-web.xml <name:service-ref> <name:service-ref-name>services/BookStore</name:service-ref-name> <name:port> <name:port-name>BookStorePort</name:port-name> <name:protocol>http</name:protocol> <name:host>localhost</name:host> <name:port>8080</name:port> <name:uri>/SecurityWebServices/bookstore</name:uri> </name:port> </name:service-ref> |
?
至此, 我们完成了一个简单的在线书库的例子。通过在浏览器输入 http://localhost:8080/SecurityWebServiceClient/,并以 Java 作为关键字检索书籍,将如 图片 2 所示。
图片 2. BookStoreClient 访问页面
目前为止,示例中的 Web Service 应用没有任何安全设置,任何客户端均可以直接访问。 在后续的章节中,我们将基于该示例展示在 Apache Geronimo 中如何使用各种安全策略来确保 Web Service 应用的安全,包括授权访问和传输安全。
基于 HTTP BASIC 安全认证策略
HTTP BASIC 的认证方式非常简单,当客户端向服务端受保护资源发起请求时,服务端会返回的消息中包括这样一个消息头 WWW-Authenticate: Basic realm="example.com",此时如果客户端是浏览器,则一个输入框将弹出,提示用户输入用户名和密码。 在用户输入用户名和密码之后,客户端使用 Base64 编码方式对用户名和密码进行加密并返回至服务端。由于我们的 Web Service 应用实质上是通过一个 Servlet 的形式对外发布, 显而易见,我们可以通过在 web.xml 和 geronimo-web.xml 中为 Servlet 对应的访问路径进行安全设置, 由此可达到对该 Web Service 应用授权访问。 请参照 清单 5 和 清单 6 。
清单 5. web.xml 配置片段
<security-constraint> <web-resource-collection> <web-resource-name>basicResources</web-resource-name> <url-pattern>/bookstore/*</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>geronimo-admin</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> |
清单 6. geronimo-web.xml 配置片段
<web:security-realm-name>geronimo-admin</web:security-realm-name> <sec:security> <sec:role-mappings> <sec:role role-name="admin"> <sec:principal name="admin" class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" /> </sec:role> </sec:role-mappings> </sec:security> |
?
在 清单 5 中设置了对访问路径 /bookstore 的任何 GET 和 POST 请求都需要使用 HTTP BASIC 认证方式,允许访问的角色为 admin。而在 清单 6 中, 指定了执行认证的安全域,出于示例方便。我们直接使用了 Geronimo 自带的 geronimo-admin 作为指定安全域,,用户完全可以定义和部署自己的安全域,同时将角色 admin 映射为安全域中的 admin 组,即当登录用户隶属于 admin 组时,其将具备对受保护资源的访问权限。 当重新部署之后, 此时再通过浏览器访问 http://localhost:8080/SecurityWebServices/bookstore?WSDL, 会提示输入用户名和密码。如 图片 3 所示。
图片 3. BookStoreImplService 访问页面
接下来,我们对 Web 客户端进行修改,使其可以访问受 HTTP BASIC 认证方式保护的 Web Service 应用。 在 JAX-WS 的 API 中, 可以通过 BindingProvider
接口来设置认证所需的用户名和密码。 请参照 清单 7
,出于示例方便, 用户名和密码采取硬编码的方式, 实际使用时可以采取更灵活的方式。
清单 7. BookStoreClient 代码片段
String queryName = request.getParameter("name"); if (queryName != null && queryName.length() > 0) { BookStore bookStore = service.getPort(BookStore.class); BindingProvider bindingProvider = (BindingProvider) bookStore; bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "system"); bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY,"manager"); request.setAttribute("books", bookStore.queryByName(queryName)); } request.getRequestDispatcher("index.jsp").forward(request, response); |
?
通过在客户端代码中添加认证信息,我们的客户端又可以访问在线书店的 Web Service 应用了。从 清单 7 可 以注意到, 用户需要修改客户端代码以添加登录所需信息。 事实上, Apache Geronimo 在应用服务器平台级别提供了相关支持, 用户可以通过在部署文件中定义 Credential Store 和指定登录信息的方式, 由应用服务器来处理登录所需事宜。下面示例中, 我们仍然使用应用服务器自带的 geronimo-admin 安全域, 在实际开发和生成环境, 用户必需定义自己的安全域以及验证模块。 详细步骤如下 :
- 停止 Apache Geronimo, 编辑 var/config/config.xml 文件, 添加如 清单 8 所示的配置信息, 并拷贝文章下载示例中的 simple_credentials.properties 文件到 var/security 目录。
- 修改客户端应用程序的部署文件 geronimo-web.xml, 添加如 清单 9 所示的配置信息。
- 删除 清单 7
中位于客户端
BookStoreClient
类中用于登录认证的相关代码。 - 启动 Apache Geronimo 应用服务器, 并重新部署 SecurityWebServiceClient 应用程序。
清单 8. config.xml
<module name="org.apache.geronimo.framework/server-security-config/2.2/car"> <gbean name="org.apache.geronimo.framework/server-security-config/2.2/car? ServiceModule=org.apache.geronimo.framework/server-security-config/2.2/car, j2eeType=LoginModule,name=simple-crddentials-login" gbeanInfo="org.apache.geronimo.security.jaas.LoginModuleGBean"> <attribute name="loginModuleClass"> org.apache.geronimo.security.realm.providers. GeronimoPropertiesFileMappedPasswordCredentialLoginModule </attribute> <attribute name="options"> credentialsURI=var/security/simple_credentials.properties </attribute> <attribute name="loginDomainName">simple-crddentials</attribute> </gbean> <gbean name="org.apache.geronimo.framework/server-security-config/2.2/car? ServiceModule=org.apache.geronimo.framework/server-security-config/2.2/car, j2eeType=LoginModuleUse,name=simple-crddentials-login-use" gbeanInfo="org.apache.geronimo.security.jaas.JaasLoginModuleUse"> <attribute name="controlFlag">REQUIRED</attribute> <reference name="LoginModule"> <pattern> <name>simple-crddentials-login</name> </pattern> </reference> </gbean> <gbean name="org.apache.geronimo.framework/server-security-config/2.2/car? ServiceModule=org.apache.geronimo.framework/server-security-config/2.2/car, j2eeType=LoginModuleUse,name=properties-login"> <reference name="Next"> <pattern> <name>simple-crddentials-login-use</name> </pattern> </reference> </gbean> </module> |
?
在 清单 8
中,我们为当前服务器默认使用的安全域的登录链添加一个新的 LoginModule GeronimoPropertiesFileMappedPasswordCredentialLoginModule
, 此模块的作用是当用户使用其所在的安全域进行认证时,会将在 simple-credentials.properties 配置文件中对应的用户名和密码信息对添加到 Subject
中
的 Private Credentials 中去。以属性文件中第一行的内容为例,system=system:system=manager,第一个
system 对应于当前登录所使用的用户名,第二个 system 为登录信息的名称,最后的 system 和 manager
则为真正使用的用户名密码信息。后续会介绍 Geronimo 如何使用保存在 Subject 中的 Private Credentials 信息为
Web Service 的访问提供平台级别支持。
?
清单 9. geronimo-web.xml 片段
<name:service-ref> <name:service-ref-name>services/BookStore</name:service-ref-name> <name:port> <name:port-name>BookStorePort</name:port-name> <name:protocol>http</name:protocol> <name:host>localhost</name:host> <name:port>8080</name:port> <name:uri>/SecurityWebServices/bookstore</name:uri> <name:credentials-name>system</name:credentials-name> </name:port> </name:service-ref> <web:security-realm-name>geronimo-admin</web:security-realm-name> <app:security xsi:type="sec:securityType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <sec:credential-store-ref> <dep:name>SimpleCredentialStore</dep:name> </sec:credential-store-ref> <sec:default-subject> <sec:realm>geronimo-admin</sec:realm> <sec:id>system</sec:id> </sec:default-subject> </app:security> <dep:gbean name="SimpleCredentialStore" class="org.apache.geronimo.security.credentialstore.SimpleCredentialStoreImpl" xsi:type="dep:gbeanType"> <dep:xml-attribute name="credentialStore"> <credential-store xmlns="http://geronimo.apache.org/xml/ns/credentialstore-1.0"> <realm name="geronimo-admin"> <subject> <id>system</id> <credential> <type> o.a.g.security.credentialstore.NameCallbackHandler </type> <value>system</value> </credential> <credential> <type> o.a.g.security.credentialstore.PasswordCallbackHandler </type> <value>manager</value> </credential> </subject> </realm> </credential-store> </dep:xml-attribute> </dep:gbean> |
?
清单 9 为 更新后的 Web Service 客户端的部署文件,相比于没有安全设置的配置,可以看出, service-ref 元素增加了一个子元素 credentials-name, 同时在安全配置中添加了 default-subject 和 credential-store-ref 两个元素。关于各项配置的含义,请参照 表格 1 :
表 1. 安全设置说明
service-ref-name/port/credentials-name | system | 该名称对应于用户名密码对的名称 |
security/credential-store-ref/name | SimpleCredentialStore | 登录时使用的 Credential Store,主要包含了登录时所使用的 CallbackHandler 信息,当前配置值指向了后续的 SimpleCredentialStore GBean |
security/default-subject/realm | geronimo-admin | 登录时使用的安全域 |
security/default-subject/id | system | 和上一行的 realm 值一起在 Credential Store 中定位到登录时所使用的 CallbackHandler 设置 |
那么 Geronimo 是如何通过以上配置来提供相关功能呢?具体步骤如下所示:
- 用户请求到达 Web Service 客户端时,Geronimo 检查到当前会话没有安全信息,则使用 default-subject 配置信息,使用从 Credential Store 中获取的 CallbackHandler 信息对 geronimo-admin 安全域执行标准的 JAAS 登录操作。
- 在对 geronimo-admin 安全域执行登录操作时,安全域登录链中包含的所有登录模块均被执行,在执行到 清单 8 中添加的 LoginModule 时,属性文件中以 system 为键值的所有登录信息均被添加到 Subject 的 Private Credential 中。
- 当执行到客户端代码中关于访问远端 Web Service 的代码时,在用户请求发送之前,Geronimo 会以 credentials-name 的配置值 system 为键值在当前会话的 Subject 中检索对应的用户名和密码信息,并通过标准 JAX-WS 方法进行设置。
如此,通过 清单 8 中关于登录模块的配置和 清单 9 中关于 Default Subject 的配置,实现了在服务器级别的安全支持,而对于 Web Service 客户端程序而言,无需在其代码中添加安全认证的逻辑。事实上,正如第三步骤所描述,Geronimo 在后台执行的代码与 清单 7 一致,相关代码位于 JAX-WS 插件中 geronimo-jaxws 的 org.apache.geronimo.jaxws.client.PortMethodInterceptor 类中 , 感兴趣的读者可以结合阅读。
另外,如果远端请求的用户名和密码与登录到当前域的用户密码是一致的,如当前示例中,则可以使用 Geronimo 另外一个 LoginModule 的实现 org.apache.geronimo.jaas.NamedUPCredentialLoginModule,并指定 org.apache.geronimo.jaas.NamedUPCredentialLoginModule.Name 选项为 credentials-name 元素的值,也可以达到同样的效果。但相比较于 清单 8 中 所使用的 GeronimoPropertiesFileMappedPasswordCredentialLoginModule 来说,略欠缺灵活性,但是工作原理一致,即将远端 Web Service 登录所需信息以 Private Credential 的形式添加到当前会话的 Subject 中。
?
使用 SSL 确保消息传输的完整性和私密性
使用上述 HTTP BASIC 的认证方式,我们达到了 Web Service 应用授权访问的目的,但是登录成功之后,服务端和客户端之间交互的 SOAP 信息也是使用明文传输, 第三方完全可以通过截取网络传输包获取 SOAP 消息的内容。而通过 SSL, 可以最大程度上弥补这一缺陷,使得 Web Service 交互的安全性得到进一步的提高。
首先, 修改 Web Service 服务端的配置文件, 将 transport-guarantee 元素的值由原来的 NONE 改成 CONFIDENTIAL, 这样将对受保护资源将使用 SSL 连接方式。 如 清单 10 所示 :
清单 10. web.xml 配置片段
<security-constraint> <web-resource-collection> <web-resource-name>basicResources</web-resource-name> <url-pattern>/bookstore/*</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL </transport-guarantee> </user-data-constraint> </security-constraint> |
?
其次, 客户端访问时, 需要使用 HTTPS 协议和端口进行访问, 将 geronimo-web.xml 文件中的 service-ref 更新如清单 11 所示 :
?
清单 11. geronimo-web.xml
<name:service-ref> <name:service-ref-name>services/BookStore</name:service-ref-name> <name:port> <name:port-name>BookStorePort</name:port-name> <name:protocol>https</name:protocol> <name:host>localhost</name:host> <name:port>8443</name:port> <name:uri>/SecurityWebServices/bookstore</name:uri> <name:credentials-name>system</name:credentials-name> </name:port> </name:service-ref> |
?
最后,关闭 Geronimo 服务器,在命令行执行 set GERONIMO_OPTS=-Djavax.net.ssl.trustStore=$YOUR_GERONIMO_HOME/var/security/keystores/geronimo-default -Djavax.net.ssl.trustStorePassword=secret, 并重新启动 Geronimo 服务器。此时 Web Service 客户端与服务端的交互, 将通过 HTTPS 进行传输 . 在设置 Trust Store 时, 可以依据实际环境使用其他方式, 比如将服务端的公钥导入 JRE 的默认 Trust Store。需要强调地是,本文示例中 Web Service 服务端和客户端使用的是同一个 Geronimo 实例,而 Geronimo 默认的 HTTPS Connector 使用的证书是 $YOUR_GERONIMO_HOME/var/security/keystores/geronimo-default, 所以设置 javax.net.ssl.trustStore 也指向同一位置。如果需要访问第三方发布并基于 HTTPS 协议传输的 Web Service 应用,则需要将其证书导入到本地的 Trust Store 中,并为以上两个参数设置合适的值。
基于 CLIENT CERT 的安全认证策略
在授权访问方面,除了基于用户名和密码的 HTTP BASIC 认证方式之外,CLIENT-CERT 也是一个比较好的选择。通常基于 HTTPS 的访问中,只需要服务端提供证书表明其身份,在之前的例子也介绍到,客户端需要将服务端的公共证书添加到本地受信密钥库中。而当使用 CLIENT-CERT 认证方式时,客户端也必需提供证书来表明自己的身份,换句话说,服务端和客户端均需要提供证书以表明各自身份。所以,CLIENT-CERT 是一种比较特殊的 SSL 使用方式。现实情况中,这种认证方式使用的不是很多,因为大多数用户并没有自己的证书,但在 B2B 场景中会见到其身影。例如两家公司之间可以使用该认证方式来确保信息交互的安全。
为示例方便,我们将使用两个 Geronimo 应用服务器实例,分别部署 Web Service 应用的服务端和客户端。为避免端口冲突,用户可以通过修改其中一台服务器实例的 var/config/config-substitutions.properties 文件中 PortOffset 的值为 10,使得两个服务器实例同时在一台机器上运行。实现步骤如下所示:
1. 使用 KeyTool 或者其他工具为 Web Service 客户端生产密钥库文件 client.jks,并导出客户端证书,再将其导入服务端受信的密钥库文件 trustedclient.jks 中。
2. 在 Web Service 服务端所在的应用服务器,通过控制台中 Web Server 配置页面,添加支持 CLIENT-CERT 方式的 HTTPS Connector。填写配置时,需要注意的是以下配置项:
表 2. CLIENT-CERT HTTPS Connector 关键配置项
keystoreFile | ../security/keystores/geronimo-admin | 服务端 HTTPS Connector 使用的密钥库文件位置 |
port | 8444 | 服务端 HTTPS Connector 监听端口 |
clientAuth | true | 是否支持 CLIENT-CERT 认证方式 |
keyAlias | 密钥库中服务端所使用证书的别名,如果不设置,则为密钥库中读取的第一个密钥 | |
keystorePass | secret | 用于访问密钥库文件的密码 |
truststoreFile | ../security/keystores/trustedclient.jks | 用户验证客户端证书的密钥库文件位置 |
truststorePass | secert | 访问受信任客户端密钥库文件的密码 |
3. 修改 Web Service 服务端部署文件,如 清单 12 所示:
清单 12. 使用 CLIENT-CERT 认证方式的 Web Service 服务端部署文件 geronimo-web.xml 片段
<web:security-realm-name>client-cert-realm</web:security-realm-name> <sec:security> <sec:credential-store-ref> <dep:name>client-cert-credential-store</dep:name> </sec:credential-store-ref> <sec:default-subject> <sec:realm>client-cert-realm</sec:realm> <sec:id>default</sec:id> </sec:default-subject> <sec:role-mappings> ...... </sec:role-mappings> </sec:security> <gbean name="client-cert-realm" class="org.apache.geronimo.security.realm.GenericSecurityRealm" xsi:type="dep:gbeanType"> <attribute name="realmName">client-cert-realm</attribute> <attribute name="global">true</attribute> <reference name="ServerInfo"> <name>ServerInfo</name> </reference> <xml-reference name="LoginModuleConfiguration"> <log:login-config xmlns:log="......"> <log:login-module control-flag="REQUIRED" wrap-principals="false"> <log:login-domain-name>client-cert-realm</log:login-domain-name> <log:login-module-class> o.a.g.security.realm.providers.PropertiesFileNoPasswordLoginModule </log:login-module-class> <log:option name="groupsURI"> var/security/groups.properties</log:option > </log:login-module> </log:login-config> </xml-reference> </gbean> <gbean name="client-cert-credential-store" class="org.apache.geronimo.security.credentialstore.SimpleCredentialStoreImpl"> <xml-attribute name="credentialStore"> <credential-store xmlns="......"> <realm name="client-cert-realm"> <subject> <id>default</id> <credential> <type> o.a.g.security.credentialstore.NameCallbackHandler </type> <value>system</value> </credential> </subject> </realm> </credential-store> </xml-attribute> </gbean> |
?
当使用 CLIENT-CERT 认证方式时,服务端和客户端之间的证书验证在 SSL 握手阶段已经完成,即一旦握手成功,表明用户身份得到确认,故而该请求具备了受保护资源的访问权限。如 清单 12 所 示,使用了与 HTTP BASIC 认证时 Web Service 客户端类似的部署配置,使用 default-subject 配置项,并结合 Security Realm 和 Credential Store 设置,为用户会话添加默认的安全设置,使之可以访问受保护的资源。
4. 修改 Web Service 客户端部署文件中的端口值,改为 8444,即服务端新建支持 CLIENT-CERT 认证方式的 HTTPS Connector 监听端口。
5. 启动 Web Service 客户端所在 Geronimo 应用服务器之前,在命令行使用 GERONIMO_OPTS 设置以下系统属性:
表 3. CLIENT-CERT 客户端系统属性设置
javax.net.ssl.trustStore | $YOUR_GERONIMO_HOME/gt/var/security/keystores/geronimo-default | 客户端受信密钥库,包含从服务端导入的公钥信息 |
javax.net.ssl.trustStorePassword | secret | 客户端受信密钥库访问密码 |
javax.net.ssl.keyStore | $YOUR_GERONIMO_HOME/gt/var/security/keystores/client.jks | 客户端密钥库,包含客户端自身的私钥信息 |
javax.net.ssl.keyStorePassword | secret | 客户端密钥库访问密码 |
从表格 3 的设置可以看出,Web Service 客户端和服务端设置是完全对等的,只是客户端是通过系统属性设置,而服务端则通过 HTTPS Connector 设置。也说明了 CLIENT-CERT 本质上是双向证书认证方式。
结束语
本文以一个简单的在线书店 Web Service 应用为例,介绍了如何基于 HTTP/HTTPS 保护 SOAP 信息交互安全。概而述之,通过 HTTP BASIC/CLIENT-CERT 实现对 Web Service 应用的授权访问,而通过 SSL 确保消息传输的完整性和私密性。实际环境中,可以基于需求选择合适的安全策略。
?
原文:http://www.ibm.com/developerworks/cn/opensource/os-cn-ag-secwebs/index.html?ca=drs-