通过 Java 从示例 XML 创建 SOAP 消息
Posted
技术标签:
【中文标题】通过 Java 从示例 XML 创建 SOAP 消息【英文标题】:Creating SOAP message from Sample XML via Java 【发布时间】:2011-10-26 03:36:31 【问题描述】:我真的很挣扎。我有一个 Web 服务要调用,它由证书和数字签名保护。所有这些都需要作为我通过 Java 代码创建的 SOAP 请求的一部分传递,但即使在花了几天时间之后,我试图创建的数字签名部分也没有正确形成。
代码正确创建请求,直到 BinaryToken 并从“Name signatureToken”中断。寻找关于代码中什么不正确的指导
这是示例 XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1">
<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 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#X509v3" wsu:Id="XWSSGID-1313056420712-845854837">MIIDVjCCAj6gAwIBAgIEThbQLTANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJnYjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEUMBIGA1UEChMLaGVhbHRoc29sdmUxFDASBgNVBAsTC2hlYWx0aHNvbHZlMQ4wDAYDVQQDEwVzaW1vbjAeFw0xMTA3MDgwOTM4NTNaFw0xMjA3MDIwOTM4NTNaMG0x</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="XWSSGID-13130564207092015610708">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsse SOAP-ENV"/>
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#XWSSGID-1313056421405-433059543">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>3wCcYA8m7LN0TLchG80s6zUaTJE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>ZkPCKEGpOmkhJA5Kq6oqUYU3OWQYyca676UhL
lOyRj7HQD7g0vS+wp70gY7Hos/2G7UpjmYDLPA==</ds:SignatureValue>
<ds:KeyInfo>
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="XWSSGID-1313056421331317573418">
<wsse:Reference URI="#XWSSGID-1313056420712-845854837" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="XWSSGID-1313056421405-433059543">
</ns2:GetEhaStatusRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我编写的通过代码形成上述 XML 的代码如下:
protected void setSecuritySection(SOAPFactory soapFactory, SOAPEnvelope envelope, SOAPPart soapPart) throws SOAPException, ECException
String METHODNAME = "setSecuritySection";
KeyPairGenerator kpg;
boolean mustUnderstand = true;
SOAPHeader soapHeader = envelope.getHeader();
try
Name securityName = soapFactory.createName("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsswssecurity-secext-1.0.xsd");
SOAPElement securityElement = soapHeader.addHeaderElement(securityName);
// SOAPHeaderElement securityElement =
// soapHeader.addHeaderElement(securityName);
// securityElement.setMustUnderstand(mustUnderstand);
Name binarySecurityToken = soapFactory.createName("BinarySecurityToken", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsswssecurity-secext-1.0.xsd");
SOAPElement binarySecurityTokenElement = securityElement.addChildElement(binarySecurityToken);
Certificate cert;
String trustStoreLocation = ServerInformation.getValueForWebsphereVariable("EHA_TRUSTSTORE");
String trustStorePwd = ServerInformation.getValueForWebsphereVariable("EHA_TRUSTSTORE_PWD");
InputStream path = new FileInputStream(trustStoreLocation);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(path, new String(new BASE64Decoder().decodeBuffer(trustStorePwd)).toCharArray());
cert = ks.getCertificate("test");
binarySecurityTokenElement.addTextNode(new BASE64Encoder().encode(cert.getEncoded()));
kpg = KeyPairGenerator.getInstance("DSA");
Name idToken = soapFactory.createName("Id", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsswssecurity-secext-1.0.xsd");
SOAPElement idElement = binarySecurityTokenElement.addChildElement(idToken);
idElement.addTextNode("test");
Name valueTypeToken = soapFactory.createName("ValueType", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
SOAPElement valueTypeElement = binarySecurityTokenElement.addChildElement(valueTypeToken);
valueTypeElement.addTextNode("X509v3");
Name encodingTypeToken = soapFactory.createName("EncodingType", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
SOAPElement encodingTypeElement = binarySecurityTokenElement.addChildElement(encodingTypeToken);
encodingTypeElement.addTextNode("Base64Binary");
Name signatureToken = soapFactory.createName("Signature", "ds", "http://www.w3.org/2000/09/xmldsig#");
SOAPHeaderElement signElement = soapHeader.addHeaderElement(signatureToken);
Name id1 = soapFactory.createName("Id");
signElement.addAttribute(id1,"XWSSGID-13130564207092015610708");
Name signedInfo = soapFactory.createName("SignedInfo");
SOAPElement signInfoElement = signElement.addChildElement(signedInfo);
//SOAPHeaderElement signInfoElement = soapHeader.addHeaderElement(signedInfo);
Name canonicalToken = soapFactory.createName("CanonicalizationMethod");
SOAPElement canonicalTokenTokenElement = signInfoElement.addChildElement(canonicalToken);
Name alg = soapFactory.createName("Algorithm");
canonicalTokenTokenElement.addAttribute(alg,"http://www.w3.org/2001/10/xml-exc-c14n#");
Name InclusiveNamespaceToken = soapFactory.createName("InclusiveNamespaces", "wsse", "http://www.w3.org/2001/10/xml-exc-c14n#");
SOAPElement element = canonicalTokenTokenElement.addChildElement(InclusiveNamespaceToken);
Name prefixList = soapFactory.createName("PrefixList");
element.addAttribute(prefixList,"wsse SOAP-ENV");
Name signatureMethodToken = soapFactory.createName("SignatureMethod","ds", "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
SOAPElement signatureMethodTokenElement = signInfoElement.addChildElement(signatureMethodToken);
Name alg2 = soapFactory.createName("Algorithm");
signatureMethodTokenElement.addAttribute(alg2,"http://www.w3.org/2000/09/xmldsig#rsa-sha1");
Name referenceToken = soapFactory.createName("Reference", "ds", "#XWSSGID-1313056421405-433059543");
SOAPElement referenceTokenElement = signatureMethodTokenElement.addChildElement(referenceToken);
Name uri = soapFactory.createName("URI");
referenceTokenElement.addAttribute(uri,"#XWSSGID-1313056421405-433059543");
Name digestMethodAlgToken = soapFactory.createName("DigestMethod");
SOAPElement digestMethodAlgTokenElement = referenceTokenElement.addChildElement(digestMethodAlgToken);
Name alg3 = soapFactory.createName("Algorithm");
digestMethodAlgTokenElement.addAttribute(alg3,"http://www.w3.org/2000/09/xmldsig#sha1");
Name digestValueToken = soapFactory.createName("DigestValue" ,"ds" , "3wCcYA8m7LN0TLchG80s6zUaTJE=");
SOAPElement digestValueTokenElement = referenceTokenElement.addChildElement(digestValueToken);
digestValueTokenElement.addTextNode("3wCcYA8m7LN0TLchG80s6zUaTJE=");
Name signValueToken = soapFactory.createName("SignatureValue");
SOAPElement signValueElement = signElement.addChildElement(signValueToken);
signValueElement.addTextNode("QlYfURFjcYPu41G31bXgP4JbFdg6kWH+8ofrY+oc22FvLqVMUW3zdtvZN==");
Name keyInfoToken = soapFactory.createName("KeyInfo") ;
SOAPElement keyInfoElement = signElement.addChildElement(keyInfoToken);
Name securityRefToken = soapFactory.createName("SecurityTokenReference" ,"wsse" , "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement securityRefElement = keyInfoElement.addChildElement(securityRefToken);
Name id2 = soapFactory.createName("Id","wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
securityRefElement.addAttribute(id2,"XWSSGID-1313056421331317573418");
Name referenceURIToken = soapFactory.createName("Reference", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-tokenprofile1.0#X509v3");
SOAPElement refElement = securityRefElement.addChildElement(referenceURIToken);
Name uri1 = soapFactory.createName("URI");
refElement.addAttribute(uri1,"#XWSSGID-1313056420712-845854837");
Name valType = soapFactory.createName("ValueType");
refElement.addAttribute(valType,"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
catch (Exception ex)
throw new SOAPException(ex);
【问题讨论】:
SOAP 消息格式没有作为示例出现。我需要用于 xml 形成的确切方法。 您是否正在“手动”创建签名的 XML 文档? 是的,我必须通过代码按原样创建示例 xml 是的。示例 XML 应该是代码的结果。 很奇怪!这样做的目的是什么?您是否考虑过使用 JDK 1.6 (javax.xml.crypto) 中提供的 XML 加密支持? 【参考方案1】:为什么不使用 Spring Web 服务安全性?
http://static.springsource.org/spring-ws/site/reference/html/security.html
【讨论】:
以上是关于通过 Java 从示例 XML 创建 SOAP 消息的主要内容,如果未能解决你的问题,请参考以下文章
Java 11 包 javax.xml.soap 不存在 [重复]
从 Java 中的 SOAPMessage 获取原始 XML
从 C# .NET Core(特别是 Workday)调用 Java Web 服务。如何在soap请求中获取xml属性