用于XML签名生成的每个元素上的SOAP标头xmlns:ds

时间:2017-03-24 14:50:14

标签: java xml web-services soap

我有rtfm但仍然有问题。我正在重读手册,但在这里发帖是因为我所做的不起作用。我得到了一个SOAP服务的xsd和wsdl文件。我从未实现过需要数字签名的客户端。我写了一个soaphandler来修改信封标题,但我无法弄清楚我做错了什么。

肥皂消费者告诉我,传入签名代的post canoncalization xml应如下所示:

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"></ds:CanonicalizationMethod>
  <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"></ds:SignatureMethod>
  <ds:Reference URI="#secinfo" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"></ds:DigestMethod>
    <ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">ZwOJboUtw1RlDspibqbyaWrKIog=</ds:DigestValue>
    <ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:XPath xmlns:ds="http://www.w3.org/2000/09/xmldsig#">//*[@id='secinfo']/child::*/text()</ds:XPath>
      </ds:Transform>
    </ds:Transforms>
  </ds:Reference>
</ds:SignedInfo>

我生成的xml看起来更像是这样:

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
  <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
  <ds:Reference URI="#secinfo">
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
    <ds:DigestValue>ZwOJboUtw1RlDspibqbyaWrKIog=</ds:DigestValue>
    <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
        <ds:XPath>//*[@id='secinfo']/child::*/text()</ds:XPath>
      </ds:Transform>
    </ds:Transforms>
  </ds:Reference>
</ds:SignedInfo>

我为处理邮件而编写的代码如下。根据我的理解,当我创建一个名为“ds”的SOAPElement和uri时,它应该如上所述正确表示。我试过addAttribute(“xmlns:ds”,“url”);对于某些元素,它仍然失败。

   @Override
public boolean handleMessage(SOAPMessageContext context) {

    try {
        if (messageOutbound(context)) {

            SOAPFactory factory     = SOAPFactory.newInstance();
            SOAPMessage soapMsg = context.getMessage();
            SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();

            SOAPHeader soapHeader = soapEnv.getHeader();

            // if no header, add one
            if (soapHeader == null) {
                soapHeader = soapEnv.addHeader();
            }

            String serverURI = "service.messages";
            soapEnv.addNamespaceDeclaration("urn", serverURI);

            String timeStamp        =  generateTimeStamp();
            timeStamp = "201703221758";

            //Create the XML headers via example
            String prefix               = "wsse";
            String uri                  =   "http://schemas.xmlsoap.org/ws/2002/04/secext";
            SOAPElement security        = factory.createElement("Security", prefix, uri);

            uri = "http://www.w3.org/2000/09/xmldsig#";

            SOAPElement signedInfo      = factory.createElement("SignedInfo", "ds", uri);



            SOAPElement canoncalized    = factory.createElement("CanonicalizationMethod", "ds", uri);
            canoncalized.setAttribute("Algorithm", "http://www.w3.org/2001/10/xml-exc-c14n#");
            canoncalized.addNamespaceDeclaration("ds", uri);




            SOAPElement signatureMethod = factory.createElement("SignatureMethod", "ds", uri);
            signatureMethod.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1");

            SOAPElement reference       = factory.createElement("Reference", "ds", uri);
            reference.setAttribute("URI", "#secinfo");

            SOAPElement digestMethod    = factory.createElement("DigestMethod", "ds", uri);
            digestMethod.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
            // up to here is good

            SOAPElement digestValue     = factory.createElement("DigestValue", "ds", uri);
            String userString = "USER=" + userID + ";CORR=" + corrNo + ";TIMESTAMP=" + timeStamp;

            String digestVal  = createDigest("sha1", userString);
            digestValue.setValue(digestVal);

            SOAPElement transforms      = factory.createElement("Transforms", "ds", uri);

            SOAPElement transform       = factory.createElement("Transform", "ds", uri);
            transform.setAttribute("Algorithm", "http://www.w3.org/TR/1999/REC-xpath-19991116");

            SOAPElement xPath           = factory.createElement("XPath", "ds", uri);
            xPath.setValue("//*[@id='secinfo']/child::*/text()");

            transform.addChildElement(xPath);

            transforms.addChildElement(transform); 

            reference.addChildElement(digestMethod);
            reference.addChildElement(digestValue);  
            reference.addChildElement(transforms);

            signedInfo.addChildElement(canoncalized); 
            signedInfo.addChildElement(signatureMethod); 
            signedInfo.addChildElement(reference); 

            SOAPElement signature       = factory.createElement("Signature", "ds", uri);

            final StringWriter sw = new StringWriter();
            TransformerFactory.newInstance().newTransformer().transform(new DOMSource(signedInfo), 
                                                                        new StreamResult(sw));

            String s = sw.toString();
            s = s.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "");
            System.out.println(s);

            //need to inisitalize the canonvalue not sure how?
            SOAPElement signatureValue  = factory.createElement("SignatureValue", "ds", uri);

            String canonValue           = canonicalize(s);

            signatureValue.setValue(createSignature("rsa-sha1", canonValue));

            SOAPElement keyInfo         = factory.createElement("KeyInfo", "ds", uri);

            SOAPElement keyName         = factory.createElement("KeyName", "ds", uri);
            keyName.setValue("BLAHBLAHBLAH");

            SOAPElement userNameToken   = factory.createElement("UsernameToken", "t", "http://schemas.xmlsoap.org/ws/2002/04/secext");
            userNameToken.setAttribute("id", "secinfo");

            SOAPElement userInfo        = factory.createElement("UserInfo", "t", "http://schemas.xmlsoap.org/ws/2002/04/secext");
            userInfo.setValue(userString);//"USER=THISUSER;CORR=THISCORR;TIMESTAMP="+timeStamp);

            //format the document from inner most to outter most


            signature.addChildElement(signedInfo);//1                
            signature.addChildElement(signatureValue);//2

            keyInfo.addChildElement(keyName);//1

            signature.addChildElement(keyInfo); //3

            security.addChildElement(signature);

            userNameToken.addChildElement(userInfo);

            security.addChildElement(userNameToken);

            soapHeader.addChildElement(security);

            soapMsg.saveChanges();

            System.out.println("Trying to print message.");

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            soapMsg.writeTo(out);
            String strMsg = new String(out.toByteArray());
            System.out.println(strMsg);

            System.out.println("End of handleMessage.");

        } else {
           //indound message not outbound 
        }

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

    return true;
}

非常感谢任何帮助。

0 个答案:

没有答案