【问题标题】:Cannot resolve element with ID while signing a part of SOAP REQUEST X509签署 SOAP REQUEST X509 的一部分时无法解析具有 ID 的元素
【发布时间】:2017-09-19 13:02:41
【问题描述】:

我在尝试签署 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属性的方法?

感谢您的帮助!

【问题讨论】:

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


    【解决方案1】:

    我找到了。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-07
      • 2013-02-27
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多