通过 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

xml SOAP示例 - AIM双帐户XML

从 C# .NET Core(特别是 Workday)调用 Java Web 服务。如何在soap请求中获取xml属性

java.lang.NoClassDefFoundError:javax/xml/soap/SOAPException

java怎么解析文本文件中的soap报文