java - 使用 WSS4J 签署 XML。没有 ID 为 "noXMLSig"的消息

标签 java soap wss4j

我正在尝试使用二进制安全 token 来发送 SOAP 消息。在 SoapUI 中一切正常,但在 Java 中我无法得到相同的结果。我正在使用 wss4j-2.2.2。

SoapUI 设置: SoapUI Signature settings

我想要实现的目标:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:stat="http://example.com/y/ws/x/">
<soapenv: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">
        <wsse:BinarySecurityToken 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/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="X509-8A99177A7EC2D385BA155346257881246">MIIP(...)Rw==</wsse:BinarySecurityToken>
        <ds:Signature Id="SIG-8A99177A7EC2D385BA155346257888650" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:SignedInfo>
                <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <ec:InclusiveNamespaces PrefixList="soapenv stat" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                </ds:CanonicalizationMethod>
                <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                <ds:Reference URI="#id-8A99177A7EC2D385BA155346257881349">
                    <ds:Transforms>
                        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                            <ec:InclusiveNamespaces PrefixList="stat" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        </ds:Transform>
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                    <ds:DigestValue>EJK(...)U=</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>hFK(...)w==</ds:SignatureValue>
            <ds:KeyInfo Id="KI-8A99177A7EC2D385BA155346257881247">
                <wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="STR-8A99177A7EC2D385BA155346257881248" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
                    <wsse:Reference URI="#X509-8A99177A7EC2D385BA155346257881246" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"/>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
        </ds:Signature>
    </wsse:Security>
</soapenv:Header>
<soapenv:Body wsu:Id="id-8A99177A7EC2D385BA155346257881349" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <stat:zapytajOStatusKomunikatu>
        <komunikat>
            <identyfikatorKomunikatu>12345</identyfikatorKomunikatu>
        </komunikat>
    </stat:zapytajOStatusKomunikatu>
</soapenv:Body>
</soapenv:Envelope>

我正在使用 WSS4J 进行签名,但收到错误:没有 ID 为“noXMLSig”的消息。我有有效的 PKCS12 keystore ,但我做错了什么。

这是我的代码:

    @Override
public boolean handleMessage(SOAPMessageContext context) {

    Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    if (outboundProperty) {
        SOAPMessage message = context.getMessage(); // <?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><S:Body><ns2:zapytajOStatusKomunikatu xmlns:ns2="http://example.com/y/ws/x/"><komunikat><identyfikatorKomunikatu>1234</identyfikatorKomunikatu></komunikat></ns2:zapytajOStatusKomunikatu></S:Body></S:Envelope>

        try {
            org.apache.xml.security.Init.init();

            String certPath = "file.p12";
            String pass = "pass";
            String alias = "alias";
            KeyStore store = KeyStore.getInstance("PKCS12");
            store.load(new FileInputStream(certPath), pass.toCharArray());      

            Document doc = message.getSOAPBody().getOwnerDocument();

            Properties properties = new Properties();
            properties.setProperty("org.apache.ws.security.crypto.provider", "org.apache.wss4j.common.crypto.Merlin");
            properties.setProperty("org.apache.wss4j.crypto.merlin.keystore.alias", alias);

            properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "PKCS12");
            properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", pass);
            properties.setProperty("org.apache.ws.security.crypto.merlin.keystore.file", certPath);

            Merlin crypto = (Merlin)CryptoFactory.getInstance(properties);
//                crypto.setKeyStore(store);


            WSSecHeader secHeader = new WSSecHeader(doc);
            secHeader.setMustUnderstand(false);
            secHeader.insertSecurityHeader();

            WSSecSignature sign = new WSSecSignature(doc);
            sign.setUserInfo(alias, pass);
            sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); // Binary Security Token - SecurityTokenReference
            sign.setSigCanonicalization(CanonicalizationMethod.EXCLUSIVE);
            sign.setDigestAlgo(DigestMethod.SHA1);

            Document signedDoc = sign.build(crypto);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return true;
}

sign.build(crypto)导致异常:

org.apache.wss4j.common.ext.WSSecurityException: No message with ID "noXMLSig" found in resource bundle "org/apache/xml/security/resource/xmlsecurity". Original Exception was a java.lang.NullPointerException and message null
Original Exception was java.lang.NullPointerException
    at org.apache.wss4j.dom.message.WSSecSignature.prepare(WSSecSignature.java:185)
    at org.apache.wss4j.dom.message.WSSecSignature.build(WSSecSignature.java:382)
    at com.example.MySOAPHandler.handleMessage(MySOAPHandler.java:165)
    at com.example.MySOAPHandler.handleMessage(MySOAPHandler.java:57)
    at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandleMessage(HandlerProcessor.java:282)
    at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandlersRequest(HandlerProcessor.java:123)
    at com.sun.xml.internal.ws.handler.ClientSOAPHandlerTube.callHandlersOnRequest(ClientSOAPHandlerTube.java:127)
    at com.sun.xml.internal.ws.handler.HandlerTube.processRequest(HandlerTube.java:112)
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:1121)
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:1035)
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:1004)
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:862)
    at com.sun.xml.internal.ws.client.Stub.process(Stub.java:448)
    at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:178)
    at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
    at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77)
    at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
    at com.sun.proxy.$Proxy106.checkStatus(Unknown Source)
    at com.example.MenuService.checkStatus(MenuService.java:1819)
    at com.example.MenuService.testAction3(MenuService.java:1795)
    at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
    at com.example.action.ActionDelegate.perform(ActionDelegate.java:157)
    at com.example.action.ActionDelegate.perform(ActionDelegate.java:152)
    at org.apache.pivot.wtk.Button.press(Button.java:453)
    at org.apache.pivot.wtk.Menu$Item.press(Menu.java:195)
    at org.apache.pivot.wtk.skin.MenuItemSkin.mouseUp(MenuItemSkin.java:144)
    at org.apache.pivot.wtk.Component$ComponentMouseButtonListenerList.mouseUp(Component.java:521)
    at org.apache.pivot.wtk.Component.mouseUp(Component.java:2952)
    at org.apache.pivot.wtk.Container.mouseUp(Container.java:845)
    at org.apache.pivot.wtk.Container.mouseUp(Container.java:845)
    at org.apache.pivot.wtk.Container.mouseUp(Container.java:845)
    at org.apache.pivot.wtk.Container.mouseUp(Container.java:845)
    at org.apache.pivot.wtk.Container.mouseUp(Container.java:845)
    at org.apache.pivot.wtk.ApplicationContext$DisplayHost.processMouseEvent(ApplicationContext.java:998)
    at java.awt.Component.processEvent(Component.java:6298)
    at org.apache.pivot.wtk.ApplicationContext$DisplayHost.processEvent(ApplicationContext.java:792)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.NullPointerException
    at org.apache.wss4j.dom.util.SignatureUtils.getInclusivePrefixes(SignatureUtils.java:78)
    at org.apache.wss4j.dom.message.WSSecSignatureBase.getInclusivePrefixes(WSSecSignatureBase.java:323)
    at org.apache.wss4j.dom.message.WSSecSignature.prepare(WSSecSignature.java:178)
    ... 61 more

我不知道我做错了什么。

最佳答案

应该是

WSSecSignature sign = new WSSecSignature(secHeader);    

而不是

WSSecSignature sign = new WSSecSignature(doc);

No message with ID "noXMLSig" found in resource bundle

实际上意味着:我找不到标题

关于java - 使用 WSS4J 签署 XML。没有 ID 为 "noXMLSig"的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55328931/

相关文章:

java - 使用 Jersey 枚举资源

Java 在数组中搜索匹配的字符串

java - 生成的 Java 类的 @XmlSeeAlso 注释中缺少类

java - 如何使用 wss4j 库验证 soap 签名

java - 如何使用Printf

Java包: What is the difference between `oracle.AQ` and `oracle.jdbc.aq` ?

vb.net - 如何向 VB.NET 2008 SOAP 请求添加 header ?

jquery - 使用 AJAX jQuery 和 SOAP 调用 WebService

grails - 如何使用 Grails-cxf 插件向 Web 服务提供动态凭据(用户名和密码)

java - Web 服务安全和 Windows 证书