扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:闹市孤僧 2007年5月30日
关键字:
组合安全策略
以上三小节所介绍的都基于单一安全策略机制,此外只在客户端应用了安全策略。有时我们可能需要在Web Service的服务和客户两端同时使用安全策略,不但保证客户端请求SOAP报文的安全性,同时也保证服务端响应SOAP报文的安全性。每一方都可以采用多种组合的安全策略,如使用数字签名+报文加密或身份认证+报文加密等组合方式。
从请求和服务的角度上看,Web Service的交互两端分为客户端和服务端,但在实施安全策略时两者是对等的。即如果客户端的请求SOAP希望使用WS-Security,客户端需要注册并配置OutHandler,服务端则相应地注册并配置InHandler。相应的,如果服务端的响应SOAP希望使用WS-Security,服务端需要注册并配置OutHandler,而客户端需要注册并配置InHandler。我们完全可以在前三小节的基础上完成所有组合的安全策略,本节将给出几个应用的例子。
服务端需要完成两件事:首先,对SOAP请求报文进行解密,接着验证数字签名的合法性,这些信息都通过WSS4JInHandler的properties属性进行设置的:
…
<bean id="bbtForumServiceEncSign" parent="baseWebService">①此处设置和其它方式并没有不同之处
<property name="serviceBean" ref="bbtForum" />
<property name="serviceClass"
value="com.baobaotao.xfire.server.BbtForumService" />
<property name="name" value="BbtForumServiceEncSign" />
<property name="inHandlers">
<list>
<ref bean="domInHandler" />
<ref bean="wss4jInHandlerEncSign" />
</list>
</property>
</bean>
<bean id="wss4jInHandlerEncSign"
class="org.codehaus.xfire.security.wss4j.WSS4JInHandler">
<property name="properties">
<props>
<prop key="action">Encrypt Signature</prop>②组合动作用空格分隔
<prop key="decryptionPropFile">③-1解密须使用server的私钥,属性文件必须提供
访问密钥库中私钥的相关配置
com/baobaotao/xfire/wss4j/server/insecurity_enc.properties
</prop>
<prop key="passwordCallbackClass">③-2密码回调实现类
com.baobaotao.xfire.wss4j.server.PasswordHandler
</prop>
④验证签名须使用client数字证书,属性文件需要提供访问密钥库client数字证书的配置
<prop key="signaturePropFile">
com/baobaotao/xfire/wss4j/server/insecurity_sign.properties
</prop>
</props>
</property>
</bean>
值得注意的是②处组合动作的设置,多个动作用空格分隔。要XFire中,动作的执行顺序和动作的编写顺序一致,如“Encrypt Signature”表示先解密再验证数字签名(对于InHandler)。properties需要通过设置分别为多个动作提供相应的配置信息。
客户端完成两个动作:先对报文进行加密,再进行数字签名,这些信息通过设置WSS4JOutHandler的properties属性达到目的:
package com.baobaotao.xfire.wss4j.client;
…
public class BbtForumServiceEncSignClient {
private static XFireProxyFactory serviceFactory = new XFireProxyFactory();
public static void main(String[] args) {
Service serviceModel = new ObjectServiceFactory().create(BbtForumService.class);
try {
String serviceURL = "http://localhost:8088/baobaotao/service/BbtForumServiceEncSign";
BbtForumService service =(BbtForumService) serviceFactory.create(serviceModel,
serviceURL);
Client client = ((XFireProxy)Proxy.getInvocationHandler(service)).getClient();
client.addOutHandler(new DOMOutHandler());
Properties properties = new Properties();
①加密属性设置:使用server数字证书进行加密
properties.setProperty(WSHandlerConstants.ACTION,①-1组合动作用空格分隔
WSHandlerConstants.ENCRYPT + " "+ WSHandlerConstants.SIGNATURE);
properties.setProperty(WSHandlerConstants.ENCRYPTION_USER, "server");
properties.setProperty(WSHandlerConstants.ENC_PROP_FILE,
"com/baobaotao/xfire/wss4j/client/outsecurity_enc.properties");
②签名属性设置:使用client私钥进行签名
properties.setProperty(WSHandlerConstants.USER, "client");
properties.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS,
PasswordHandler.class.getName());
properties.setProperty(WSHandlerConstants.SIG_PROP_FILE,
"com/baobaotao/xfire/wss4j/client/outsecurity_sign.properties");
properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "IssuerSerial");
client.addOutHandler(new WSS4JOutHandler(properties));③所有属性在此总装
int count = service.getRefinedTopicCount(20);
System.out.println("count:"+count);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
①-1处的组合动作设置和服务端的一样使用空格分隔多个动作,特别要小心的是,客户端的组合动作的顺序必须和服务端的相同,否则将引起错误。
客户端同时使用加密和签名的安全策略后,就可以保证请求SOAP报文的保密性、完整性和不可抵赖性,解决信息安全领域三个最关键的问题。
服务端在接收客户端请求SOAP报文时,需要使用server私钥进行解密处理,在发送响应SOAP报文时需要使用client的数字证书进行加密处理。
…
<bean id="bbtForumServiceEnc2Way" parent="baseWebService">
<property name="serviceBean" ref="bbtForum" />
<property name="serviceClass"value="com.baobaotao.xfire.server.BbtForumService" />
<property name="name" value="BbtForumServiceEnc2Way" />
<property name="inHandlers">①对请求SOAP报文进行解密处理
<list>
<ref bean="domInHandler" />
<ref bean="wss4jInHandlerEnc2Way" />
</list>
</property>
<property name="outHandlers">②对响应SOAP报文进行加密处理
<list>
<ref bean="domOutHandler" />
<ref bean="wss4jOutHandlerEnc2Way" />
</list>
</property>
</bean>
<bean id="wss4jInHandlerEnc2Way"class="org.codehaus.xfire.security.wss4j.WSS4JInHandler">
<property name="properties">
<props>
<prop key="action">Encrypt</prop>
<prop key="decryptionPropFile">
com/baobaotao/xfire/wss4j/server/insecurity_enc.properties
</prop>
<prop key="passwordCallbackClass">
com.baobaotao.xfire.wss4j.server.PasswordHandler
</prop>
</props>
</property>
</bean>
<bean id="domOutHandler"class="org.codehaus.xfire.util.dom.DOMOutHandler" />
<bean id="wss4jOutHandlerEnc2Way"
class="org.codehaus.xfire.security.wss4j.WSS4JOutHandler">
<property name="properties">
<props>
<prop key="action">Encrypt</prop>
<prop key="encryptionUser">client</prop>
<prop key="encryptionPropFile">
com/baobaotao/xfire/wss4j/server/outsecurity_enc.properties
</prop>
</props>
</property>
</bean>
和先前我们配置的Web Service最大的区别在于我们用粗体部分的代码定义了OutHandler,它们将对响应的SOAP报文使用client的数字证书进行加密处理。outsecurity_enc.properties属性文件定义了访问serverStore.jks的访问信息。
由于请求SOAP和响应SOAP都进行了加密,所以客户端需要采用和服务端相似的设置方式,注册InHandler对响应SOAP报文进行解密,注册OutHandler对请求SOAP报文进行加密:
package com.baobaotao.xfire.wss4j.client;
…
public class BbtForumServiceEnc2WayClient {
private static XFireProxyFactory serviceFactory = new XFireProxyFactory();
public static void main(String[] args) {
Service serviceModel = new ObjectServiceFactory().create(BbtForumService.class);
try {
String serviceURL =
"http://localhost:8088/baobaotao/service/BbtForumServiceEnc2Way";
BbtForumService service = (BbtForumService) serviceFactory.create(
serviceModel, serviceURL);
Client client = ((XFireProxy) Proxy.getInvocationHandler(service)).getClient();
①注册OutHandler,用server数字证书对请求SOAP报文进行加密
①-1将DOM模型的请求SOAP转换为STAX流模型
client.addOutHandler(new DOMOutHandler());
Properties properties_1 = new Properties();
properties_1.setProperty(WSHandlerConstants.ACTION,
WSHandlerConstants.ENCRYPT);
properties_1.setProperty(WSHandlerConstants.ENCRYPTION_USER,
"server");
properties_1
.setProperty(WSHandlerConstants.ENC_PROP_FILE,
"com/baobaotao/xfire/wss4j/client/outsecurity_enc.properties");
client.addOutHandler(new WSS4JOutHandler(properties_1));①-2 进行加密处理
②注册InHandler,用client私钥对响应的SOAP报文进行解密
②-1将STAX流模型的响应SOAP转换为DOM模型
client.addInHandler(new DOMInHandler());
Properties properties_2 = new Properties();
properties_2.setProperty(WSHandlerConstants.ACTION,
WSHandlerConstants.ENCRYPT);
properties_2
.setProperty(WSHandlerConstants.DEC_PROP_FILE,
"com/baobaotao/xfire/wss4j/client/insecurity_enc.properties");
properties_2.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS,
PasswordHandler.class.getName());
client.addInHandler(new WSS4JInHandler(properties_2));②-2进行解密处理
int count = service.getRefinedTopicCount(20);
System.out.println("count:" + count);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
关于属性文件的具体信息,请参看随书光盘的内容,我们不再展开说明。按照相似的方式,我们还可以让客户端服务端都采用数字签名+报文加密的方式,实现双向的安全。
小结
Web Service是分布式的应用,SOAP报文可能在不安全的传输层传输,应用安全受到极大的挑战。WS-Security是专门为解决Web Service应用安全而制定的规范,XFire通过Apache的WSS4J对WS-Security提供了完整的支持。XFire通过注册一系列的InHandler和OutHandler对接收和发送的SOAP报文进行安全处理,Web Service的业务逻辑对WS-Security是透明的。
首先,我们独立地讲解了使用UsernameToken进行身份认证、对SOAP报文进行数字签名、对SOAP报文进行加密的WS-Security实施方法。进而,我们还讲解了如何在客户端和服务端使用组合的安全策略。相信读者朋友可以在此基础上举一反三,进行各种组合安全策略的应用。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者