I had requested Marcus to do some preliminary investigation into supporting the SAML Token Profile of WSS using PicketLink for JBoss WS.

We had an IRC chat with Marcus and Stefan which is copy/pasted here.

(09:27:40 AM) anil: marcus: ping luck with JBWS?
(09:29:23 AM) marcus: anil: sort of. i know we have to implement a handler so we get access to the soap message and extract the SAML assertion
(09:29:40 AM) anil: marcus: yeah. did u figure out where?
(09:29:56 AM) marcus: anil: what i'm trying to understand now is what do they do with the username and password
(09:30:19 AM) anil: marcus: they send it to JAAS afaik
(09:30:33 AM) marcus: anil: so far i can see they have a SecurityAdaptor where they set thread local objects
(09:30:51 AM) marcus: anil: but i don't see how that goes into the callbackhandler
(09:31:03 AM) anil: marcus: to be honest, all I care is 1 handler that takes the security stuff and calls PL and moves on.
(09:31:18 AM) anil: marcus: I see your point.
(09:31:21 AM) anil: marcus: let me think.
(09:32:07 AM) marcus: anil: sooner or later that should go into the invocation (in case of an ejb3 ws for example)
(09:32:23 AM) marcus: anil: i can't find that on the ws code yet
(09:32:55 AM) anil: marcus: I am rying to think how the CBH gets involved in web and ejb layer.
(09:33:09 AM) anil: marcus: jaassec mgr
(09:33:31 AM) anil: marcus: see if they have any injection of jaas sec mgr
(09:33:53 AM) marcus: anil: right.... but in ejb case we have an interceptor that retrieves username/credential from the invocation and call jaassecmgr
(09:34:20 AM) anil: marcus: u looking in the ws-security code that Jason Greene did. correct?
(09:34:33 AM) marcus: anil: yes
(09:35:03 AM) anil: marcus: http://anonsvn.jboss.org/repos/jbossws/stack/native/trunk/
(09:35:14 AM) anil: marcus: can u navigate to the code where this is and give me the link?
(09:36:48 AM) marcus: anil: http://anonsvn.jboss.org/repos/jbossws/stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/security/operation/ReceiveUsernameOperation.java
(09:36:53 AM) anil: ok
(09:37:04 AM) marcus: anil: see the process method. that's where they set username/credential
(09:37:32 AM) marcus: anil: we probably just need to set the credential as a SamlCredential
(09:37:46 AM) anil: marcus: I am looking at process() method.
(09:37:52 AM) anil: marcus: now let me get to the adaptor.
(09:38:14 AM) anil: marcus: my initial thought was to have the STS token as SamlCredential and handle in the LM.
(09:38:32 AM) anil: marcus: but we may need handlers to call the PL STS to get a token for example for outbound calls.
(09:39:18 AM) anil: marcus: here is an example: (username,pass) ->JBWS; JBWS(callSTS-use username/pass, get token) ->Web
(09:39:20 AM) marcus: anil: the handler takes care of inbound and outbound calls
(09:39:42 AM) anil: marcus: but the WS layer should be calling STS for getting a token?
(09:39:56 AM) anil: marcus: wait. the LM can do that.
(09:40:11 AM) anil: marcus: but we wont replace the original (username,cred) with (username,SAML)?
(09:41:07 AM) marcus: anil: stefan's implementation only validates the SamlCredential... the assertion contains the username
(09:42:08 AM) anil: marcus: u r missing my point.
(09:42:32 AM) anil: marcus: we can do the sts calling etc. but we cannot replace the original security context (securityassociation, sca etc) for what we do in LM.
(09:42:47 AM) stefan: marcus: we need to check if the server-side interceptors accept null usernames. If they do, then we can just send (null, SAML). If not, we will need to set the assertion subject as username
(09:43:15 AM) anil: marcus: I mean the LM can call sts, get a token. But how can we replace the outbound security ctx with the new saml token
(09:44:34 AM) stefan: anil: I don't think we should be replacing things in WS. Either the person chooses to use username/pw or SAML. In the client side some piece of code needs to set the assertion in the SOAP header, it is the client's responsibility to get the assertion. We just validate the whole thing
(09:44:57 AM) marcus: stefan: that's what i thought too
(09:45:10 AM) marcus: anil: i don't think our handler should call sts to get a token
(09:45:17 AM) anil: marcus: stefan: not the handlers.
(09:45:20 AM) marcus: anil: it should be provided by the client
(09:45:57 AM) anil: marcus: stefan: but it should be possible for a client to call an JBWS and configuration in LM (STSInitiatingLM) to get a saml token for outbound calls
(09:46:27 AM) anil: marcus: stefan: LM stack will look: (usernamepasswordmodule), (stsinitiatingLM)
(09:46:32 AM) stefan: anil: yea, but in the Web layer we can use a Filter to replace the sec context, I don't think we can do that with web services
(09:48:23 AM) marcus: stefan: anil: http://anonsvn.jboss.org/repos/jbossws/stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/security/jaxws/WSSecurityHandler.java
(09:48:45 AM) stefan: anil, marcus: and I think using redirection is a better solution for Web apps (user is redirected to an STS wep app, authenticates there, receives the assertion and redirects the assertion to the Web container as part of the HTTP request. This is better than exchanging the token on the server side
(09:48:52 AM) marcus: stefan: anil: the handler have access to the soap message for outbound calls... we can add anything we want there
(09:49:27 AM) anil: marcus: I agree with ur approach.
(09:49:29 AM) stefan: marcus: there you go. So you can use this to add the assertion to the SOAP message.
(09:49:46 AM) anil: marcus: we can add the saml assertion into the soap header and handle it as an handler at the other end
(09:49:53 AM) anil: marcus: got it.
(09:50:10 AM) anil: marcus: stefan: I am going to copy this conversation into a design thread.
(09:50:39 AM) anil: marcus: see. wss has the saml token profile. we need to use that. :)
(09:51:12 AM) marcus: anil: cool. i just need to figure out where that SecurityAdaptor comes into play :)
(09:52:52 AM) stefan: anil: marcus: true. The profile probably specifies how assertions should be added to the SOAP header. We also must consider signing part of the request message to prove possession of the token
(09:54:06 AM) stefan: anil: marcus: something similar is done by the X509 authentication they have in place. You can sign the SOAP message to prove possession of the private key that corresponds to the public key being sent.
(09:55:05 AM) anil: stefan: we just have to look at the saml token profile to get more info.
(09:58:33 AM) stefan: anil: marcus: I think adding something to SOAP and retrieving it/passing to JAAS on server-side is not that difficult. I feel we can have this simple scenario working in 1-2 weeks. Now, signing stuff to prove possession of the assertion and verifying the signature can be a bit more complicated. But as anil said, we need to look at the SAML profile and see what's in there
(10:06:11 AM) marcus: stefan: i think the signing part is already done in WS code

Additionally, we have the JAX-WS handlers created by Daniel Bevenius.

(10:20:10 AM) stefan: anil: ESB? but he is calling a WS attaching the assertion in the SOAP payload
(10:26:13 AM) stefan: marcus: anil: I think we are losing track of things. If ESB has a handler to include assertions in the request, we should look into it
(10:27:39 AM) marcus: stefan: the user is adding the assertion to the payload... not ESB
(10:27:59 AM) anil: marcus: PL is included as tech preview in SOA-P 5
(10:28:05 AM) stefan: marcus: are you sure? he has a handler in there, didn't look into it
(10:29:03 AM) stefan: marcus: this handler, to be more specific: <jws:handler-class>org.picketlink.identity.federation.core.wstrust.handlers.STSSaml20Handler</jws:handler-class>
(10:29:29 AM) marcus: stefan: looking...
(10:30:24 AM) stefan: marcus: anil: the point is, I don't really care if it is ESB code or not, the fact is that passing SAML assertions as part of the payload is already implemented - at least the client-side of it
(10:30:34 AM) anil: stefan: man.
(10:32:04 AM) anil: stefan: http://anonsvn.jboss.org/repos/picketlink/federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/wstrust/handlers/STSSecurityHandler.java
(10:32:12 AM) anil: stefan: looks like he did jaxws handlers
(10:32:26 AM) anil: stefan: but not sure that really works with our JBWS native wss stuff.
(10:32:40 AM) stefan: anil: that's what I'm saying
(10:33:08 AM) stefan: anil: think we have tests for this?
(10:33:34 AM) anil: stefan: it should be in the esb project.
(10:34:46 AM) marcus: anil: stefan: i think that works yes... he is just not using JAAS
(10:34:55 AM) stefan: anil: looks like this handler validates the assertion directly, no JAAS involved. I wonder how useful this really is if it doesn't set any security context
(10:35:06 AM) stefan: marcus: exactly
(10:36:14 AM) stefan: marcus: but it just validates, no security context is set from what I'm seeing. This means the Web Service won't get anything when calling getUserPrincipal from WSContext
(10:43:58 AM) anil: stefan: marcus: I think we should add a ws test case for this handler and start progress from there. Our integration test project can be used?
(10:45:28 AM) stefan: anil: marcus: probably. But we will need a new handler or one that extends the current handler to propagate the call to JAAS and let the server set the security context

(10:34:46 AM) marcus: anil: stefan: i think that works yes... he is just not using JAAS
(10:34:55 AM) stefan: anil: looks like this handler validates the assertion directly, no JAAS involved. I wonder how useful this really is if it doesn't set any security context
(10:35:06 AM) stefan: marcus: exactly
(10:36:14 AM) stefan: marcus: but it just validates, no security context is set from what I'm seeing. This means the Web Service won't get anything when calling getUserPrincipal from WSContext
(10:43:58 AM) anil: stefan: marcus: I think we should add a ws test case for this handler and start progress from there. Our integration test project can be used?
(10:45:28 AM) stefan: anil: marcus: probably. But we will need a new handler or one that extends the current handler to propagate the call to JAAS and let the server set the security context

This is correct that there is no setting of a security context in the WS-Handlers nor does the handler use JAAS.

I'm not sure what has been decided here about moving forward, if you are going to modify the current handlers or simply write new ones, but if I can help with anything then please let me know. I could for example verify that the new handlers work with the JBoss ESB saml quickstart if nothing else.

I've been playing a bit with the sample in the article, and modified the picketlink-trust-jbossws-native classes a bit to actually make the project jbossws-stack agnostic (iow it would not depend on jbossws-native anymore, but on jbossws-common only). As a matter of fact, you're not leveraging jbossws native implementation stuff there except for very few minor things.

Next step would be to prepare and try another client and endpoint using jbossws-cxf; it should be possible to re-use the modified picketlink-trust-jbossws project and just use the cxf means of configuring and endpoint/interceptor that runs before application handlers.

Is there any chance I can commit to picketlink-trust-jbossws, or would you like patches for this?

On a different topic, to build picketlink-trust-jbossws-native from sources I ended up building picketlink-federation, which in turns seems to require picketlink-seam. The latter builds here into org.jboss.picketlink:picketlink-seam:jar (I'm using mvn 2.2.1), while the artifact required by picketlink-federation is org.picketlink:picketlink-seam:jar (no "jboss" in the groupId). I patched this locally to complete the build, but I wonder if I'm missing something here...

ATM the picketlink-trust-jbossws (I've removed the -native from the name, see if you also want to svn move the sources to a different dir) is not using any stack specific thing. At the current status, the SAML2Handler can be used as any other standard JAXWS handler, meaning you can add it on both client and server side either programmatically (through BindingProvider:getBinding():getHandlerChain()) or using the @HandlerChain annotation.

I've tested a modified version of the sample both with Native and CXF stack:

The difference of this approach is that the handler is at the same level of any other jaxws handler the user might want to add to the application, while handlers declared as post-handlers in the jbossws-native-endpoint/client xml are ensured to be always run before/after the user ones (depending on the message direction). This is most probably not an issue in this case though. In any case for the CXF client I'm going to find out how to properly install interceptors running similarly to jbossws-native post-handlers (I also need that for other reasons), so I'll let you know, but you should be ok for now.

More generally, I assume future step would probably be to try achieving a more deep integration, using this in conjunction with sign/encrypt of the payload.. etc...

I can most probably easily work on removing the jbossws-common dependency too by adding some further code in the SAML2Handler. However if we come to a solution for properly configuring ( in a stack agnostic way ) the handlers as "special" ones instead of standard user jaxws handlers (see above), that's still going to require something jbossws specific (jbossws-spi / jbossws-common stuff). So perhaps we can evaluate this again in future.