xsul.dsig.globus.security.authentication.SOAPBodyIdResolver.java Source code

Java tutorial

Introduction

Here is the source code for xsul.dsig.globus.security.authentication.SOAPBodyIdResolver.java

Source

/*
This file is licensed under the terms of the Globus Toolkit Public
License, found at http://www.globus.org/toolkit/download/license.html.
*/
package xsul.dsig.globus.security.authentication;

import xsul.dsig.globus.security.authentication.wssec.WSConstants;
import xsul.dsig.globus.security.authentication.wssec.WSSecurityUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.signature.XMLSignatureInput;
import org.apache.xml.security.utils.XMLUtils;
import org.apache.xml.security.utils.resolver.ResourceResolverException;
import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
import org.apache.xml.utils.URI;
import org.apache.xpath.CachedXPathAPI;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.util.Set;

/**
 * This resolver is used for resolving same-document URI like URI="#id".
 * It is desgined to only work with SOAPEnvelopes. It looks for the Id in the
 * first child elemenet of the Body element.
 *
 */
public class SOAPBodyIdResolver extends ResourceResolverSpi {
    private static Log logger = LogFactory.getLog(SOAPBodyIdResolver.class.getName());
    private static SOAPBodyIdResolver resolver;

    public synchronized static ResourceResolverSpi getInstance() {
        if (resolver == null) {
            resolver = new SOAPBodyIdResolver();
        }

        return resolver;
    }

    public XMLSignatureInput engineResolve(Attr uri, String BaseURI) throws ResourceResolverException {
        String uriNodeValue = uri.getNodeValue();
        NodeList resultNodes = null;
        Document doc = uri.getOwnerDocument();

        // this must be done so that Xalan can catch ALL namespaces
        XMLUtils.circumventBug2650(doc);

        CachedXPathAPI cXPathAPI = new CachedXPathAPI();

        /*
         * URI="#chapter1"
         * Identifies a node-set containing the element with ID attribute
         * value 'chapter1' of the XML resource containing the signature.
         * XML Signature (and its applications) modify this node-set to
         * include the element plus all descendents including namespaces and
         * attributes -- but not comments.
         */
        String id = uriNodeValue.substring(1);

        Element selectedElem = WSSecurityUtil.findFirstBodyElement(doc);

        if (selectedElem == null) {
            throw new ResourceResolverException("generic.EmptyMessage", new Object[] { "Body element not found" },
                    uri, BaseURI);
        }

        String cId = selectedElem.getAttributeNS(WSConstants.WSU_NS, "Id");

        if ((cId == null) || (cId.length() == 0)) {
            cId = selectedElem.getAttributeNS(WSConstants.SOAP_SEC_NS, "id");
        }

        if (!id.equals(cId)) {
            selectedElem = (Element) selectedElem.getParentNode();
            cId = selectedElem.getAttributeNS(WSConstants.WSU_NS, "Id");

            if ((cId == null) || (cId.length() == 0)) {
                cId = selectedElem.getAttributeNS(WSConstants.SOAP_SEC_NS, "id");
            }

            if (!id.equals(cId)) {
                throw new ResourceResolverException("generic.EmptyMessage", new Object[] { "Id not found" }, uri,
                        BaseURI);
            }
        }

        try {
            resultNodes = cXPathAPI.selectNodeList(selectedElem, Canonicalizer.XPATH_C14N_WITH_COMMENTS_SINGLE_NODE//.XPATH_C14N_OMIT_COMMENTS_SINGLE_NODE
            );
        } catch (javax.xml.transform.TransformerException ex) {
            throw new ResourceResolverException("generic.EmptyMessage", ex, uri, BaseURI);
        }

        Set resultSet = XMLUtils.convertNodelistToSet(resultNodes);
        XMLSignatureInput result = new XMLSignatureInput(resultSet);//, cXPathAPI);

        result.setMIMEType("text/xml");

        try {
            URI uriNew = new URI(new URI(BaseURI), uri.getNodeValue());
            result.setSourceURI(uriNew.toString());
        } catch (URI.MalformedURIException ex) {
            result.setSourceURI(BaseURI);
        }

        return result;
    }

    public boolean engineCanResolve(Attr uri, String BaseURI) {
        if (uri == null) {
            return false;
        }

        String uriNodeValue = uri.getNodeValue();

        return uriNodeValue.startsWith("#");
    }
}