Wednesday May 27, 2009

SAML token as Initiator Token in Asymmetric Binding with ProtectTokens

The ProtectTokens feature in the current metro version has not been implemented fully and currently we are working on this feature .A bug(wsit:issue 206) related to SAML assertions and ProtectTokens has already been filed on this.

This blog is about how we have fixed the above mentioned bug.

In the Asymmetric binding case,when we use SAML token as an InitiatiorToken with ProtectTokens enabled, the SAML token which we are using for performing Signature should also be signed .

So metro generates some STRID for SAML token to be signed ,but the major problem here is that the SAML assertion ID is not available until the callback handler is invoked.Thus the signature reference would have a non existent id which will cause an exception at runtime like :

javax.xml.ws.WebServiceException: Could not find Reference #ff63e9e3-248d-4f77-8802-5326d58da1a9 under Signature with ID1
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.handleSignature(SecurityRecipient.java:842)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.processSecurityHeader(SecurityRecipient.java:745)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.createMessage(SecurityRecipient.java:526)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.validateMessage(SecurityRecipient.java:193)
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.verifyInboundMessage(SecurityPipeBase.java:455)
at com.sun.xml.wss.jaxws.impl.SecurityServerPipe.process(SecurityServerPipe.java:177)
...................
...................
...................

So when using SAML token as Initiator token with ProtectTokens feature , in the saml callback handler  set the assertion id of the assertion on to the saml  callback handler as shown below (assume we are using saml hok type)

public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i=0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof SAMLCallback) {
                try{
                    SAMLCallback samlCallback = (SAMLCallback)callbacks[i];
                    if (samlCallback.getConfirmationMethod().equals(samlCallback.SV_ASSERTION_TYPE)){
                            samlCallback.setAssertionElement(createSVSAMLAssertion());
                            //samlCallback.setAssertionElement(createSVSAMLAssertion20());
                            svAssertion=samlCallback.getAssertionElement();
                    }else if (samlCallback.getConfirmationMethod().equals(samlCallback.HOK_ASSERTION_TYPE)){
                            samlCallback.setAssertionElement(createHOKSAMLAssertion());
                            //samlCallback.setAssertionElement(createHOKSAMLAssertion20());
                            hokAssertion=samlCallback.getAssertionElement();
                       samlCallback.setAssertionId(samlId);

                    }else{
                            throw new Exception("SAML Assertion Type is not matched.");
                    }
                }catch(Exception ex){
                        ex.printStackTrace();
                }
            } else {
                throw unsupported;
            }
        }
    }

Metro would then pick up the assertion id from the saml callback and modify the signature reference to refer to the saml assertion, thus overcoming the missing reference problem.

You can try the same with latest metro builds 

A full SAML Callback Handler can be found here

test samples can be found here

SAMLServer

SAMLClient


About

Suresh Mandalapu

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today