4

我正在使用 CXF 来使用 Web 服务

<SignedInfo>它涉及使用我的私钥签署节点并加密<soap:Body>节点。

我正在使用WSS4JOutInterceptor对肥皂消息进行签名。

我无法弄清楚如何指定 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>

**我还尝试截取消息,以便我可以从肥皂信封中获取标题并可以自己更新指纹值。但我无法在 Interceptor 中获得 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
4

0 回答 0