Я пытаюсь спеть сообщение SOAP с двоичным токеном безопасности. В SoapUI все работает нормально, но я не могу получить тот же результат в Java. Я использую wss4j-2.2.2.
Настройки SoapUI:
Чего я пытаюсь достичь:
<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 для подписи, но получаю сообщение об ошибке: нет сообщения с идентификатором "noXMLSig". У меня есть действующее хранилище ключей PKCS12, но я делаю что-то не так.
Вот мой код:
@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
Я не знаю, что я делаю не так.