在签署SOAP REQUEST X509的一部分时无法解析带ID的元素

时间:2017-09-19 13:02:42

标签: soap java-7 x509 ws-security xml-signature

尝试签署SOAP请求的一部分时出现以下错误:

org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID _53ea293168db637b15e2d4d7894
at org.apache.xml.security.utils.resolver.implementations.ResolverFragment.engineResolve(ResolverFragment.java:86)
at org.apache.xml.security.utils.resolver.ResourceResolver.resolve(ResourceResolver.java:279)
at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Reference.java:417)
at org.apache.xml.security.signature.Reference.dereferenceURIandPerformTransforms(Reference.java:597)
at org.apache.xml.security.signature.Reference.calculateDigest(Reference.java:689)
at org.apache.xml.security.signature.Reference.generateDigestValue(Reference.java:396)
at org.apache.xml.security.signature.Manifest.generateDigestValues(Manifest.java:206)
at org.apache.xml.security.signature.XMLSignature.sign(XMLSignature.java:595)

它来自参考标记上声明的URI的解析。

以下是我用于通过X509签名的java代码:

    KeyStore.PrivateKeyEntry pke = ISKeyStoreManager.getInstance().getPrivateKeyEntry(keyStoreAlias, keyAlias);


    AlgorithmStrings algStrings = AlgorithmStrings.getAlgDSStrings( pke.getPrivateKey(), signatureAlgorithmString, digestAlgorithmString);

    String resultantXPath = StringUtils.join(xpaths, '|');

    Transforms transforms = new Transforms(originalDocument);

    NodeList targetDocumentList = obtainNodesForXPath(originalDocument, resultantXPath, nc);

    if(targetDocumentList != null && targetDocumentList.getLength() > 0)
    {

        if(targetDocumentList.item(0).hasAttributes()){
            Node attrId = targetDocumentList.item(0).getAttributes().getNamedItem("Id");
            if(attrId != null && !attrId.getNodeValue().equals("")){
                uri = new StringBuilder().append('#').append(attrId.getNodeValue()).toString();
            }
            else{

                ((Element) targetDocumentList.item(0)).setAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
                ((Element) targetDocumentList.item(0)).setAttribute("wsu:Id", idForXmlObject);
            }
        }
        else{

            ((Element) targetDocumentList.item(0)).setAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            ((Element) targetDocumentList.item(0)).setAttribute("wsu:Id", idForXmlObject);
        }
    }else{
        log.debug("Target not found in the original document with xpath: " + resultantXPath);
    }

    transforms.addTransform("http://www.w3.org/2000/09/xmldsig#enveloped-signature");

    if (resultantXPath != null) {
        log.debug("Instantiation XPATHContainer");
        XPathContainer xpathC = new XPathContainer(originalDocument);
        xpathC.setXPath(resultantXPath);

        if ((ncMap != null) && (!ncMap.isEmpty())) {
            for (Map.Entry<String,String> e : ncMap.entrySet()) {
                log.debug("Adding namespace to XPATH Container: " + e.getKey() + " -> " + e.getValue());
                xpathC.setXPathNamespaceContext(e.getKey(), e.getValue());
            }
        }
        transforms.addTransform("http://www.w3.org/TR/1999/REC-xpath-19991116", xpathC.getElement());
    }
    log.debug("Instantiation Signature");
    XMLSignature sig = new XMLSignature(originalDocument, null, algStrings.signatureAlgorithm, canonicalizationAlg);

    sig.setFollowNestedManifests(true);
    log.debug("Ajout des assertions de transformation");
    sig.addDocument("", transforms, algStrings.digestMethod);

    if (idAttrForSignature != null) {
        sig.setId(idAttrForSignature);  
    }

    log.debug("DOMToString: " + serializeDOMToString(originalDocument));

    // signature node insertion
    NodeList nodeList = obtainNodesForXPath(originalDocument, insertSignatureAtXPath, nc);

    if(nodeList != null && nodeList.getLength() > 0){
        Node nodeSignature = nodeList.item(0);
        Node childNode = nodeSignature.getFirstChild();
        if (childNode != null) {
            if (addSignatureAsLastElement)
                nodeSignature.appendChild(sig.getElement());
            else
                nodeSignature.insertBefore(sig.getElement(), childNode);
        }
        else nodeSignature.appendChild(sig.getElement());
    }
    else{
        throw new ServiceException("INVALID_SIGNATURE_NODE_SELECTOR_XPATH");
    }


    // Public key insertion     
    //X509Data x509Data = getX509Data(includeCertChain, certificateData, originalDocument, pke);

    //KeyInfoReference kir = new KeyInfoReference(x509Data.getDocument());
    SecurityTokenReference str = new SecurityTokenReference(sig.getKeyInfo().getDocument());
    str.setKeyIdentifier(ISKeyStoreAccessorUtil.getIaikCertificate(pke.getCertificate()));
    sig.getKeyInfo().getElement().appendChild(str.getElement());

    log.debug("DOMToString: " + serializeDOMToString(originalDocument));

    //sig.getSignedInfo().addResourceResolver(new ResolverXPointer());

    ((Element)(sig.getSignedInfo().getElement().getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Reference").item(0))).setAttribute("URI", uri);   

    log.debug("DOMToString: " + serializeDOMToString(originalDocument));
    //sig.addDocument(uri, trans);
    // Signature generation 
    sig.sign(pke.getPrivateKey());

你有任何解决方法吗?或者另一种设置URI属性的方法?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我找到了。

我添加了InclusiveNamespaces,以便sign方法可以确定ID是在特定的命名空间定义属性上。