Some time ago, with WSS4J 1.6.x, I had a problem where if I was building a SAML
token that contained another signed SAML token in its Advice, the signature on
the inner token would be stripped clean - there'd be an element, but it would
have empty <SignatureValue/> and <DigestValue/> elements. The stripping
occurred during the call to sa.signAssertion(). I had traced the problem to
the calls to ReleaseDOM() in the AssertionWrapper.setSignature() call, and so
worked around it by writing a custom signAssertion that is pretty much the same
as what's in AssertionWrapper, but replacing setSignature with some code I
cribbed from OpenSAML.
I bring this up now because with WSS4J2, this solution isn't working for me,
because of the NPE exception I mentioned previously (it is fixed in that spot,
but this is a different spot where I am calling OpenSAML methods directly, so
the same fix doesn't apply). So I thought I'd revert back to the
SamlAssertionWrapper.signAssertion() method. But, that has the same problem as
WSS4J 1.6 - the Advice assertion has its signature stripped. As I recall, when
ReleaseDOM() is called, it releases the existing signature values so that when
WSS4J later signs the Assertion (I think I remember that the actual signing is
deferred until later?) those values are already lost, and what gets built is an
empty signature object. Since I need my Advice Assertions to retain their
signature, that doesn't work for me.
So my workaround would probably still apply if I could get past the marshalling
NPE ... can you tell me how you did that?
For what is is worth, this is what I replaced setSignature with ... my NPE's
come in with the call to "marshall".
protected final void addSignatureToAssertion(SamlAssertionWrapper sa,
Signature signature,
String signatureDigestAlgorithm)
{
if ( sa.getXmlObject() instanceof SignableSAMLObject ) {
SignableSAMLObject signableObject = (SignableSAMLObject)
sa.getXmlObject();
signableObject.setSignature(signature);
SAMLObjectContentReference contentRef =
(SAMLObjectContentReference)signature.getContentReferences().get(0);
contentRef.setDigestAlgorithm(signatureDigestAlgorithm);
try {
if ( sa.getSaml1() != null ) {
xmlObjectRegistry.getMarshallerFactory().getMarshaller(sa.getSaml1()).marshall(sa.getSaml1());
} else if ( sa.getSaml2() != null ) {
xmlObjectRegistry.getMarshallerFactory().getMarshaller(sa.getSaml2()).marshall(sa.getSaml2());
}
} catch ( MarshallingException e ) {
e.printStackTrace();
}
try {
Signer.signObject(signature);
} catch ( SignatureException e ) {
e.printStackTrace();
}
}
}
Thanx,
Stephen W. Chappell