我正在使用CXF来使用网络服务
它涉及使用我的私钥对<SignedInfo>
节点进行签名,并加密<soap:Body>
节点。
我正在使用 WSS4JOutInterceptor 来签署soap消息。
我无法弄清楚如何指定WSS4J来签署<SignedInfo>
标头节点。
另外,我想在标题中添加自定义指纹。我猜服务提供商使用它来识别他们必须使用的公钥。
下面是我现在使用我在评论中使用的Java代码生成的Soap Header
<soap:Header>
<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">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-3">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<!--
Have to transform body and message control block
Did it using
outProps.put(WSHandlerConstants.SIGNATURE_PARTS, "{Element} {http://schemas.xmlsoap.org/soap/envelope/}Body;{Element}{https://checkout.buckaroo.nl/PaymentEngine/}MessageControlBlock");
I am not sure wether us should be SIGNATUE_ or ENCRYPT_ PARTS
-->
<ds:Reference URI="#id-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>Ougg/udU=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-2">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>9cObhmiilqw=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<!--
Also have to generate a signature value which should be of the SignedInfo node
outProps.put(WSHandlerConstants.ACTION, "Signature");
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_sign.properties");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,ClientCallbackHandler.class.getName());
-->
<ds:SignatureValue>
no6CvOuwhLNGVOP1ByuICAVnSFTNq77QQttl4GIgHzatxr/ldna6yf36kufuzsHNx2n0Fp1k/05WZF9UPnzw=
</ds:SignatureValue>
<ds:KeyInfo Id="KI-AB3C213816422">
<wsse:SecurityTokenReference wsu:Id="STR-AB3C213816422">
<!--
Have to include my custom Thumbprint value here in wsse:KeyIdentifier node
outProps.put(WSHandlerConstants.SIG_KEY_ID, "Thumbprint");
-->
<wsse:KeyIdentifier
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">
z9576mEB7M7uRGq1vXGxwX4w4A0=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
<!--
This block I have added manually using
List<Header> headersList = new ArrayList<Header>();
MessageControlBlock messageControlBlock = new MessageControlBlock();
messageControlBlock.setWebsiteKey("I6t2");
messageControlBlock.setCulture("123L");
ObjectFactory factory = new ObjectFactory();
JAXBElement<MessageControlBlock> messCtlBlock = factory.createMessageControlBlock(messageControlBlock);
JAXBContext context = JAXBContext.newInstance(https.checkout_buckaroo_nl.paymentengine.MessageControlBlock.class);
Header messageControlBlockElement = new Header(
new QName("https://checkout.buckaroo.nl/PaymentEngine/", "MessageControlBlock"),
messageControlBlock,
new JAXBDataBinding(context));
headersList.add(messageControlBlockElement);
provider.getRequestContext().put(Header.HEADER_LIST, headersList); -->
<MessageControlBlock xmlns="https://checkout.buckaroo.nl/PaymentEngine/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="id-2">
<WebsiteKey>I6tNcjYiMt</WebsiteKey>
<Culture>nl-NL</Culture>
</MessageControlBlock>
</soap:Header>
&#13;
**我也尝试拦截邮件,以便我可以从肥皂信封中获取标题,并且我自己可以更新指纹值。 但是我无法在拦截器中获得Signature值。
**
public class HeaderInterceptor extends AbstractSoapInterceptor {
public HeaderInterceptor() {
super(Phase.PRE_PROTOCOL_ENDING);
getAfter().add(org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor.SAAJOutEndingInterceptor.class.getName());
}
public void handleMessage(SoapMessage message) throws Fault {
System.out.println("HeaderInterceptor");
List<Header> headers = message.getHeaders();
System.out.println("Version is " + message.getVersion());
Map<String, List<String>> headersw = CastUtils.cast((Map)message.get(Message.PROTOCOL_HEADERS));
System.out.println("Headers w is " + headersw);
message.getInterceptorChain().forEach(chain -> {
System.out.println(chain.getClass());
});
Header security = message.getHeader(
new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security")
);
System.out.println("Security header is " + security);
headers.stream().forEach(head ->{
System.out.println(head.getName().getLocalPart());
});
}
}
以上程序的输出
Version is org.apache.cxf.binding.soap.Soap11@5404d5
Headers w is {Accept=[*/*], SOAPAction=["https://checkout.buckaroo.nl/PaymentEngine/CentralSoapGateway/InvoiceInfo"]}
class org.apache.cxf.jaxws.interceptors.HolderOutInterceptor
class org.apache.cxf.jaxws.interceptors.SwAOutInterceptor
class org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor
class org.apache.cxf.binding.soap.interceptor.SoapHeaderOutFilterInterceptor
class org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor
class org.apache.cxf.interceptor.MessageSenderInterceptor
class com.testapp.commons.MyLogInterceptor
class org.apache.cxf.interceptor.AttachmentOutInterceptor
class org.apache.cxf.interceptor.StaxOutInterceptor
class org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor
class org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor
class org.apache.cxf.interceptor.WrappedOutInterceptor
class org.apache.cxf.interceptor.BareOutInterceptor
class org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal
class org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor$SoapOutEndingInterceptor
class org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor
**class com.testapp.commons.HeaderInterceptor**
class org.apache.cxf.interceptor.StaxOutEndingInterceptor
class org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor
Security header is null
MessageControlBlock