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

Reply via email to