- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想将 wsse:security 添加到我的 soap 消息中。这是我的代码:
public Document signSoapMessage(SOAPMessage message) {
try {
Document doc = message.getSOAPBody().getOwnerDocument();
Crypto crypto = CryptoFactory.getInstance(properties); //File
WSSecHeader secHeader = new WSSecHeader(doc);
secHeader.insertSecurityHeader();
InputStream inStream = new FileInputStream(properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.file"));
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(inStream, properties.getProperty("privatekeypassword").toCharArray());
String alias = ks.aliases().nextElement();
X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
WSSecSignature sign = new WSSecSignature(secHeader);
sign.setX509Certificate(cert);
sign.setUserInfo(properties.getProperty("org.apache.ws.security.crypto.merlin.keystore.alias"), properties.getProperty("privatekeypassword"));
sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); // Binary Security Token - SecurityTokenReference
sign.setUseSingleCertificate(true);
sign.setDigestAlgo(DigestMethod.SHA1);
//sign.build(crypto);
Document signedDoc = sign.build(crypto);
return signedDoc;
} catch (SOAPException e) {
e.printStackTrace();
return null;
} catch (WSSecurityException e) {
e.printStackTrace();
throw new RuntimeException("Error: " + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (CertificateException e) {
e.printStackTrace();
return null;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (KeyStoreException e) {
e.printStackTrace();
return null;
}
}
它适用于 soapenv:Body(它确实添加了 wsu:Id 和 xmlns:wsu 参数)
但是在soapenv:Header 中有一个额外的元素并且它没有对这个元素进行签名。没有wsu:Id 和xmlns:wsu 参数,也缺少一个ds:Reference。
未签名 SOAP 消息示例:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<!-- this element should be signed but is not - NOT WORKING -->
<something>
</something>
</soapenv:Header>
<!-- this element should be signed and It does. -->
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>
我将我的程序中的 soap msg 与 SoapUI 项目中的工作 soap msg 进行比较。
当我向 Web 服务发布消息时,出现错误:wsse:InvalidSecurity - Soap Header must be signed
。在 SoupUI 中它确实有效。
所以我的问题是如何强制 WSS4j 在 soapenv:Header 中签署额外的元素?
最佳答案
好的,我已经解决了这个问题。
通常这段代码应该适用于我的情况。
//strange static method from apache o.O
org.apache.xml.security.Init.init();
List<WSEncryptionPart> wsEncryptionParts = new ArrayList<>();
WSEncryptionPart somethingPart = new WSEncryptionPart("something","somethingNamespace","");
wsEncryptionParts.add(somethingPart);
sign.addReferencesToSign(wsEncryptionParts);
然而,它不起作用。它总是抛出异常:
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 org.apache.wss4j.common.ext.WSSecurityException and message No message with ID "noEncElement" found in resource bundle "org/apache/xml/security/resource/xmlsecurity"
我找不到我的 soap 消息或代码有什么问题的答案。
但是,经过一段时间的 org.apache.wss4j.dom.message.WSSecSignature 调试。我觉得这个类有问题。我决定修改一个方法 build(Crypto cr)。
public Document build(Crypto cr) throws WSSecurityException {
LOG.debug("Beginning signing...");
this.prepare(cr);
if (this.getParts().isEmpty()) {
this.getParts().add(WSSecurityUtil.getDefaultEncryptionPart(this.getDocument()));
// --- Here is my edit - And it works!
WSEncryptionPart aaa = new WSEncryptionPart("something","somethingNamespace","");
this.getParts().add(aaa);
// ----------------------------------
} else {
Iterator var2 = this.getParts().iterator();
label33:
while(true) {
while(true) {
if (!var2.hasNext()) {
break label33;
}
WSEncryptionPart part = (WSEncryptionPart)var2.next();
if (part.getId() == null && "STRTransform".equals(part.getName())) {
part.setId(this.strUri);
} else if ("KeyInfo".equals(part.getName()) && "http://www.w3.org/2000/09/xmldsig#".equals(part.getNamespace()) && part.getElement() == null) {
Element keyInfoElement = this.getKeyInfoElement();
part.setElement(keyInfoElement);
}
}
}
}
List<javax.xml.crypto.dsig.Reference> referenceList = this.addReferencesToSign(this.getParts());
this.computeSignature(referenceList);
if (this.bstToken != null) {
this.prependBSTElementToHeader();
}
return this.getDocument();
}
当然,解决方案很弱。然而,至少它现在有效。
最新版本存在的问题:
wss4j-ws-security-dom 2.2.2
wss4j-ws-security-common 2.2.2
关于java - WSSE - 在 soapenv :Header 中签署一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56701257/
我收到错误“找不到元素soapenv:Envelope 的声明” 与其他 xml 文件 xsd 一起工作正常..问题在于以下文件.. 我的 Xml 文件是:-
我正确地给出了所有请求,但无法得到响应。它显示版本不匹配错误。 请求集 XML
我想将 wsse:security 添加到我的 soap 消息中。这是我的代码: public Document signSoapMessage(SOAPMessage message) {
我正在寻找如何删除 的解决方案使用基于 XML 的路由 (Apache Camel Blueprint XML) 的 SOAP 请求的一部分。 所以这个: ...
我必须使用工具来生成 SOAP 请求,它可以通过两种方式来实现。生成以以下开头的请求: 或与: 我怀疑一种是当前技术,另一种是遗留技术。但是由于只有一个在 url 中有类似日期的东西,我无法弄清楚
我尝试使用 http://www.freeformatter.com/xml-validator-xsd.html 根据我的 XSD 验证我的 XML但它因上述错误而失败。我发现了许多相同的问题,但没
有没有办法制作一个通常生成这样的 XML 的 C#/.NET Web 服务 像这样生成
我尝试为工作应用程序(spring、hibernate、soap、cxf)实现集成测试。我手动构建 SOAP-XML 并将其处理到我的端点。像这样: private Source createRequ
我正在为电子商务网站开发一个 Web 服务,我正在将基于某些 supplier_id 的所有产品从 java 返回到 php 客户端,但它给了我这个错误 Fatal error: Uncaught S
我有一个 SOAP 请求:- 58 和 SOAP 响应:- The Data ret
我在通过 Suitetalk API 连接到 NetSuite 生产帐户时遇到以下错误: 我在连接到此客户端的 Sandbox 帐户时没有遇到任何问题。我正在通过 C# WCF 项目进行连接。我不认为
我正在使用 netsuite ruby gem ( https://github.com/RevolutionPrep/netsuite )。 我和gem的创始人谈过,我是用正确的方式抓交易的:
Below is the code import java.io.File; import java.io.IOException; import javax.xml.XMLConstant
我是一名优秀的程序员,十分优秀!