2015-06-17 41 views
0

我目前正在使用Apache CXF創建一個使用Java的SOAP客戶端。我已經從一個給定的WSDL生成了服務類,並以編程方式配置客戶端(只是爲了說清楚,我沒有使用Spring配置)。使用CXF和WSS4J創建信封簽名

我打電話的服務有要求我發送的每個請求都需要簽名。

我到目前爲止所做的是創建我的客戶端並添加WSS4JOutInterceptor以簽署消息。

Client client = ClientProxy.getClient(soapService.getRawSoapInterface()); 

//Actually not sure if this is really needed? 
QName signatureQName = new QName("http://www.w3.org/2000/09/xmldsig#", "Signature"); 
Map<String, Object> properties = new HashMap<String, Object>(); 
Map<QName, Object> processorMap = new HashMap<QName, Object>(); 
processorMap.put(WSSecurityEngine.SIGNATURE, signatureQName); 
properties.put("wss4j.processor.map", processorMap); 
properties.put(WSHandlerConstants.USER, "clientSignatureAlias"); 
properties.put(WSHandlerConstants.PW_CALLBACK_CLASS, MyPwCallback.class.getName()); 
properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); 
properties.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE); 
properties.put(WSHandlerConstants.SIG_PROP_FILE, "client.properties"); 
properties.put(WSHandlerConstants.ENC_KEY_ID, "X509KeyIdentifier"); 

WSS4JOutInterceptor wssOutInterceptor = new WSS4JOutInterceptor(properties); 

我client.properties包含:

org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin 
org.apache.wss4j.crypto.merlin.keystore.type=jks 
org.apache.wss4j.crypto.merlin.keystore.password=secret 
org.apache.wss4j.crypto.merlin.keystore.alias=cert_sig 
org.apache.wss4j.crypto.merlin.keystore.file=clientCerts.jks 

到目前爲止好,並且每個消息得到簽署。

讓我們來解決這個問題: 問題是,攔截器將這些安全頭放入Soap-Request中。

<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1"> 

起初我不是他們,第二點是我打電話的服務不知道他們,因此正在回答一個例外。

目前我找不到方法如何避免這種情況,有什麼建議嗎?

回答

0

就我所知,WSS4J根本無法創建Enveloped Signature!

因此我進入另一個方向。我使用Apache Santuario爲我的消息創建簽名。

我用CXF的Intercepor機制來創建我自己的攔截器,這裏提供了這個用例的抽象類:How To Modify The Raw XML message of an Outbound CXF Request?http://coheigea.blogspot.ie/2014/03/apache-santuario-xml-security-for-java.html

因爲我對請求一些進一步的修改,我能:

在那裏,我能叫聖所STAX的API來創建一個有效的簽名,這是在以下博客描述的非常好修改原始字符串。

感謝上帝,SOAP是標準化協議,每個人都在做他想做的事...