I've fixed this issue locally. For anyone who is interested, my fix is this: 
when the RST has ActAs, I disable signing in the SAMLTokenProvider (see below), 
then perform my own signature within my SAMLCustomHandler. My signature mostly 
reuses the WSS4J code, but I don't perform any of the DOM operations that WSS4J 
performs when signing, so that the original signature on the Advice Assertion 
remains intact. 

Thanx,

Stephen W. Chappell

-----Original Message-----
From: Chappell, Stephen CTR (FAA) 
Sent: Monday, March 16, 2015 8:36 AM
To: users@cxf.apache.org
Subject: RE: Adding Advice in CXF 2.7.13 STS 

Well, the issue I'm having is definitely occurring during the signing 
operation. The handleActAs method below is called by my SamlCustomHandler's 
handle method, which I neglected to post earlier because it's main mission in 
life is to route between a SAML1 custom handler and a SAML2 custom handler. But 
I made one other small change this morning, to disable signing in the 
SAMLTokenProvider when there is an ActAs in play that will result in an Advice 
element:

    public void handle(AssertionWrapper assertionWrapper, 
TokenProviderParameters tokenParameters)
        throws STSException
    {
        TokenRequirements tokenRequirements = 
tokenParameters.getTokenRequirements();
        ReceivedToken actAs = tokenRequirements.getActAs();

        if ( actAs != null ) {
            if ( actAs.isUsernameToken() || actAs.isBinarySecurityToken() || 
!actAs.isDOMElement() ) {
                throw new STSException("Illegal token type in ActAs element");
            }

            samlTokenProvider.setSignToken(false);

            String tokenType = tokenRequirements.getTokenType();

            if ( WSConstants.WSS_SAML_TOKEN_TYPE.equals(tokenType) ) {
                saml1CustomHandler.handleActAs(assertionWrapper, actAs, 
tokenParameters);
            } else if ( WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType) ) {
                saml2CustomHandler.handleActAs(assertionWrapper, actAs, 
tokenParameters);
            }
        } else {
                samlTokenProvider.setSignToken(true);
        }

With the setSignToken(false) in place, the assertion that gets issued has an 
Advice element with an Assertion that has its signature intact. Of course, the 
parent assertion is unsigned now, so that is my next problem to solve.

Stephen W. Chappell

From: Chappell, Stephen CTR (FAA)
Sent: Friday, March 13, 2015 3:09 PM
To: users@cxf.apache.org
Subject: Adding Advice in CXF 2.7.13 STS

I am revisiting some STS code I was working on some time ago and found a sort 
of major bug. I have a requirement to issue tokens with Advice when my RST has 
an ActAs. At the time, I implemented that using a SAMLCustomHandler derivative, 
which seemed to work until I started writing validators. Then I noticed that 
the signature value was getting stripped out of the advice assertion.

My handling code looks like this:

    public void handleActAs(AssertionWrapper assertionWrapper, ReceivedToken 
actAs)
    {
        Advice advice = (Advice)buildXMLObject(Advice.DEFAULT_ELEMENT_NAME);
        AssertionWrapper adviceAssertion = null;

        try {
            adviceAssertion = new AssertionWrapper((Element)actAs.getToken());
        }
        catch ( WSSecurityException ex ) {
            throw new STSException("Cannot handle ActAs token");
        }

        if ( adviceAssertion != null && adviceAssertion.getSaml1() != null ) {
            advice.getAssertions().add(adviceAssertion.getSaml1());
            assertionWrapper.getSaml1().setAdvice(advice);
        } else {
            LOG.log(Level.INFO, "ActAs is not SAML1");
        }
    }

(there's similar code for SAML2). When I do this, my signature on the inner 
assertion ends up like this:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#";>
<ds:SignedInfo>
                                <ds:CanonicalizationMethod 
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                                <ds:SignatureMethod 
Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                                <ds:Reference 
URI="#_0A9C1B4AD3BAA6657514262401210901">
                                                <ds:Transforms>
                                                                <ds:Transform 
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                                                                <ds:Transform 
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                                                </ds:Transforms>
                                                <ds:DigestMethod 
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                                                <ds:DigestValue/>
                                </ds:Reference>
                </ds:SignedInfo>
<ds:SignatureValue/>

Originally, the digest method was SHA256 and there were digest and signature 
values. Am I screwing something up when I add the assertion? Does anyone have 
any suggestions for tracking this down?

I have seen this before when mixing some WSS4J and OpenSaml assertion building, 
but aside from the Advice that's not really the case here. I did fix that case, 
but those fixes will not readily translate to hear. Has anyone successfully 
added Advice in the STS?

Thanx,

Stephen W. Chappell

Reply via email to