Friday, February 11, 2011

How to retrieve an OAuth token from a WS-Trust based Security Token Service (STS)

I'm finally back home after 4 straights days in airports. During the week I delivered a really interesting use case that I wanted to share. This was in support of a demo where the customer wanted to understand how OAuth works with the XML Gateway. Given the natures of POCs, I had already built much of the demo around the customer's other requirement - retrieving a SAML assertion via a WS-Trust based STS. I had to come up with a way to add the OAuth functionality to the existing scenario. I think the approach that I came up with is novel and so I wanted to share it on the blog.

If you look at a WS-Trust RST (Request for Security Token) message, the initiator can request a token type, so the call to the STS can reasonably start with a request for an OAuth token, but the real question is "What to return and how to return it?". One thing that I liked about this particular scenario was that it gave me a change to dig a little more deeply into OAuth 1.0. I think I understand it much better. There have been many places where OAuth has been explained, so I won't cover everything, but basically for the Gateway scenario calling a service protected with OAuth, you need an access token and a corresponding access token secret. For the purposes of this scenario, I assumed that the access token and access token secret were already available to the STS - let's just say this happens when the user elects to allow the gateway application access to its information.

So, then how should we return this information. Both the access token and access token secret are just strings. The solution I used was to return them as Attribute Statements inside of a SAML assertion. One of the great things about SAML is its ability to include attributes related to the subject. The eliminated the need to come up with a custom token or simply pass them pack in the transport. The transport is OK, but I like the elegance of using SAML and quite frankly how easy it was to implement using the gateway.

On the caller side, I needed to modify the request to the STS to have the right token type
and then retrieve the assertion from the response.

The XML Gateway has a single filter that retrieves attribute assertions...couldn't have been easier.
On the STS side, this was also really simple. I just added a branch in the STS policy to handle the case where an OAUTH token has requested and the call the policy to add the SAML Attribute Assertion.
A quick re-deploy of the policy and I was in business. For the purposes of this demo, I used the LinkedIn API which is protected by OAuth, and made a simple call to get my network updates for the day.

I did all of this in about 1 hour very late at night - another strong testimony for the tool. The fact that I could get and set the SAML assertions so easily, really made the whole thing "just work".

I know that OAuth 2.0 has a binding for passing a SAML assertion to retrieve an access token, but the convergence between SAML and OAuth is definitely underspecified.
The scenario I'm showing here is the binding of an OAuth access token to a SAML assertion. From a specification perspective, I think all you would need to formalize are the constants for requesting the token from the STS (token type) and the attribute names (OAuth access token) themselves. I'll get Mark on it after he gets back from RSA :)

No comments:

Post a Comment