Well, I'm either making progress or finding more places to bog down in. As 
before, I am still trying to insert a SAML assertion into the WS-Security 
header as a signed supporting token. This is in part being handled by a 
descendant class of WSSecSignature, which includes a local version of build 
that is largely the same as the base class, except that it tries to insert the 
SAML assertion into the header; the problem is that it doesn't work. Here is 
the function, stripped a bit for space:

        public Document build(Document doc, Crypto cr, WSSecHeader secHeader,
                AssertionWrapper assertion)
                throws WSSecurityException
        {
            prepare(doc, cr, secHeader, assertion);
            SOAPConstants soapConstants = 
                    WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());

            if (this.parts == null) {
                ...
            } else {
                ...
            }

            List<javax.xml.crypto.dsig.Reference> referenceList = 
addReferencesToSign(this.parts, secHeader);
            
            WSSecurityUtil.prependChildElement(secHeader.getSecurityHeader(),
                    this.assertionSecRef.getElement());
            
            // Place the assertion into the header before the signature element.
            try {
                
WSSecurityUtil.prependChildElement(secHeader.getSecurityHeader(),
                        (Element) assertion.toDOM(doc));
            }
            catch (WSSecurityException e2) {
                throw new WSSecurityException(
                    WSSecurityException.FAILED_SIGNATURE, "noSAMLdoc", null, e2
                );
            }
            
            if (bstToken != null) {
                prependBSTElementToHeader(secHeader);
            }

            computeSignature(referenceList);
            
            return doc;
        }
        
The issue here is the prependChildElement(..., (Element) assertion.toDOM(doc)). 
In the original code that I'm porting, assertion was an OpenSAML 1 
SAMLAssertion object; now it is an AssertionWrapper holding an OpenSAML 2 
Assertion object (saml1 for now, saml2 eventually). Calling 
assertion.toDOM(doc) at this point in the code throws out all the DOM and 
rebuilds it, resulting in an exception:

Caused by: org.apache.ws.security.WSSecurityException: Error during Signature: 
        at 
gov.faa.swim.ssri.wss.wss4j.saml.SupportingSamlTokenSignedAction.execute(SupportingSamlTokenSignedAction.java:114)
        at 
org.apache.ws.security.handler.WSHandler.doSenderAction(WSHandler.java:232)
        at 
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor.access$200(WSS4JOutInterceptor.java:52)
        at 
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:265)
        at 
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:141)
        at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
        at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:570)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:479)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)
        at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
        at 
org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:136)
        ... 36 more
Caused by: org.apache.ws.security.WSSecurityException: Signature creation 
failed (Cannot convert SAML to DOM document)
        at 
gov.faa.swim.ssri.wss.wss4j.saml.SupportingSamlTokenSignedAction$WSSecSamlSupportingTokenSignature.build(SupportingSamlTokenSignedAction.java:177)
        at 
gov.faa.swim.ssri.wss.wss4j.saml.SupportingSamlTokenSignedAction.execute(SupportingSamlTokenSignedAction.java:110)
        ... 47 more
Caused by: org.apache.ws.security.WSSecurityException: Error signing a SAML 
assertion
        at 
org.apache.ws.security.saml.ext.OpenSAMLUtil.signObject(OpenSAMLUtil.java:236)
        at 
org.apache.ws.security.saml.ext.OpenSAMLUtil.signXMLObject(OpenSAMLUtil.java:216)
        at 
org.apache.ws.security.saml.ext.OpenSAMLUtil.toDom(OpenSAMLUtil.java:164)
        at 
org.apache.ws.security.saml.ext.OpenSAMLUtil.toDom(OpenSAMLUtil.java:115)
        at 
org.apache.ws.security.saml.ext.AssertionWrapper.toDOM(AssertionWrapper.java:305)
        at 
gov.faa.swim.ssri.wss.wss4j.saml.SupportingSamlTokenSignedAction$WSSecSamlSupportingTokenSignature.build(SupportingSamlTokenSignedAction.java:174)
        ... 48 more
Caused by: org.opensaml.xml.signature.SignatureException: Signature computation 
error
        at org.opensaml.xml.signature.Signer.signObject(Signer.java:80)
        at 
org.apache.ws.security.saml.ext.OpenSAMLUtil.signObject(OpenSAMLUtil.java:234)
        ... 53 more
Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: 
Cannot resolve element with ID _FAE9B96DF73872EEBA14164791703639091

There is more, but that seems to be the relevant part. I have tried instead 
using assertion.getElement() so I don't have to rebuild the DOM, but that 
causes a separate problem - at some point later in the execution (the exception 
is from somewhere else entirely), I end up getting an exception stating this: " 
org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different 
document than the one that created it." Researching that reveals that the DOM 
needs to be imported into the parent node, which I would have thought would 
happen with the prepend statements.

So now I'm at a loss - how can import the existing DOM for the SAML assertion 
into the security header so that it can be signed as a signed supporting token? 
Does anyone have any ideas?

Thanx,

Stephen W. Chappell

Reply via email to