调用产生异常为:org.apache.ws.security.WSSecurityException: WSHandler: Check Signature confirmation: stored SV vector not empty
问题解决过程:
1、跟踪代码发现该异常的原因是:客户端默认开启了enableSignatureConfirmation标识,这样客户端就需要验证ws返回的xml里面的wsse:SignatureConfirmation信息,而服务端却在axis2.xml中设置了<parameter name="enableSignatureConfirmation">false</parameter>,服务端若设置为true,则要求请求的接收方确认响应中包括了来自请求的所有签名,否则验证不通过;所以不会在返回的xml中有wsse:SignatureConfirmation信息,故而出错!
2、添加设置properties1.setProperty(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "false");后再测,刚才的异常是没有了,但是却出现了新的异常,而且已经不能正常返回接口值了!
异常为:org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: WSS4JInHandler: security processing failed (actions mismatch)
导致上面的原因是在WSS4J里面,客户端在验证服务端返回的xml有效性的时候要求:验证的顺序一定要和服务端设置一致;比如我们服务端对返回xml设置了Timestamp和Signature,那么客户端设置的InHandler中对应的action也必须是Timestamp和Signature,并且顺序要一致,否则就会验证不通过(这个在wss4j的mail list中有很多人认为这是一个bug,这个要求太强制了,wss4j也承诺后续将这个实现也改掉);
3、修改设置properties1.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE);之后问题解决;
在查上面这个问题的时候,顺便还check了下关于signatureKeyIdentifier的问题,因为前面的工程师有段注释:
总结起来,signatureKeyIdentifier的取值范围可以为:IssuerSerial, Thumbprint, SKIKeyIdentifier, X509KeyIdentifier, DirectReference;其中X509KeyIdentifier, DirectReference两者是将证书信息直接暴露在请求的soap xml中;而其他三者只保存对证书的标识性信息,接收端可以根据这些信息到证书库中取出具体的证书来进行相应的操作;各种情况在soap xml中的具体标识见备注,至于选择哪种参数这个要看自己的需求了,是否需要将证书暴露这是一个可参考原则;
经测试,各种signatureKeyIdentifier取值在java环境下基于wss的web service调用均不存在任何问题,只是对应soap请求xml有所区别而已;在对其他平台是否有影响我还不确认,可能会有问题,因为我的同事在调试WSE3.0时提到过这个问题,具体可以参见这篇文章《Web Service 、WS-Security、Java和.net的互通(在路上-基于SCA规范的应用服务框架成长记之四)》,后续我会再确认一把;
另外,该标识只需要请求发起方设置即可,接收方并不需要和发起方做相同配置(这点和验证action操作不同);
备注:
signatureKeyIdentifier = IssuerSerial时soap xml为: