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