我目前正在使用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">
起初我不是他們,第二點是我打電話的服務不知道他們,因此正在回答一個例外。
目前我找不到方法如何避免這種情況,有什麼建議嗎?