Enterprise Integration Zone is brought to you in partnership with:

Mark O'Neill is VP Innovation at Axway. Previously, he was CTO and co-founder at Vordel, acquired by Axway in 2012. He is the author of the McGraw-Hill book "Web Services Security" and is frequent speaker at conferences including Java One, the RSA Security Conference, and Oracle Open World. Mark is based on Boston, Massachusetts. Mark is a DZone MVB and is not an employee of DZone and has posted 64 posts at DZone. You can read more from them at their website. View Full User Profile

How to Read in a SAML Assertion from a REST STS and Insert it Into a HTTP Header

05.12.2013
| 1742 views |
  • submit to reddit

It is a common scenario that an API Server must call out to a Security Token Service (STS) "off to the side" in order to get a SAML assertion issued for a user. This SAML Assertion then then usually inserted into the request, often as a HTTP header. Let's see how this is done with the Axway/Vordel API Server...

Firstly, I've setup an STS policy which is a "REST STS" (or "RESTS" for short). It takes in a UserID as a REST parameter and issues a SAML Assertion for that user. Here is the RESTS policy for this, below. Note that it's being served from the same API Server instance, but it could be served from another instance, or another product altogether could be issuing the SAML Assertion:


Looking at the policy above, we see the steps are:

1) Use the "Extract REST Request Attributes" filter to extract the attributes from the REST request. These attributes are the parameters being passed as part of the REST request.

2) We copy the "userid" parameter from the REST request into the "authentication.subject.id" parameter, and also populate the other two parameters which are needed for the "Insert SAML Authentication Assertion" filter we will be using later in the policy. The filter now looks like this:


3) We use a simple "Set Message" filter to create a SOAP wrapper into which we will put our SAML Assertion. This looks like this:


4) We then insert out SAML Assertion, and I put "REST STS" as the issuer name. I also choose "Sender Vouches" as the Subject Confirmation Method. 
5) Finally I round out the policy with a "Reflect Message" to return the SAML Assertion back to the client.

This policy allows me to get a freshly-minted SAML Assertion for a request containing a UserID passed as a QueryString parameter. Here is a screenshot of me running it below:


So next, let's look at the policy which calls this REST STS. Here's a screenshot of it in Policy Studio:
At a high level, this policy is firstly authenticating the client, then it is calling out to an STS to get a SAML Assertion for the client, then it is inserting that SAML Assertion into a HTTP Header. Note the Store and Restore filters which are used. These are used if you want to store the incoming message before calling out to the STS, because the message will be overwritten by the response from the STS. Note that if you're receiving a HTTP GET request initially, you don't need to use Store and Restore, simply because there is no message to store and restore.

Let's look at some of the filters which are used in this policy:

1) HTTP Digest Authentication. This is just standard usage of this filter, in this case against the Local User Store.

2) Store Message. Again, nothing special here. I'm using this filter with the default values.

3) Call REST STS. This is where it gets interesting. Notice I am passing the
${authentication.subject.id} parameter as a parameter to my REST STS:

If we had been calling a more traditional WS-Trust STS, I would have used a "Set Message" to create the RequestSecurityToken message, then used a "Set HTTP Verb" filter to set the verb to "POST", then a "Connect to URL" filter to connect to the STS.

4) "Retrieve SAML Assertion from message". This is a "Retrieve from message" filter which is reading the SAML Assertion which is returned from the STS. I am using XPath to do this. Notice that I am using the XPath Wizard (the little magic wand icon) and a sample message, to test my XPath. I am also using the "Serialize all nodes in the nodelist" option, because I want to retrieve the entire SAML Assertion into a nodelist:
5) Restore Message. This is restoring the original message (which was over-written by the response from the STS, when we called out to the STS "off to the side").

6) "Add SAML Assertion". This is where we add the SAML Assertion, Base64-encoded, as a HTTP Header (note that if we wanted to place the SAML Assertion into an XML message, we'd use "Add XML Node")


So that is how we call out to a REST STS "Off to the side", retrieve a SAML Assertion, and then place the SAML Assertion into a HTTP Header, using the Axway/Vordel API Server.
Published at DZone with permission of Mark O'neill, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)