Friday, 15 June 2012

Handling SWT Tokens from ACS (Part Two)

The full code from this blog is now available on GitHub as a reference implementation.

In Part One of this series of blogs I showed you how to set up Windows Azure's ACS to provide SWT tokens to a client over OAuth WRAP using a Service Identity. In this post I'll show you how you can parse and validate this token.

Parsing the token

At the end of Part One we successfully got token back from ACS using a WebClient. The raw response looked similar to this:

wrap_access_token=http%253a%252f%252fschemas.xmlsoap.org%252fws%252f2005%252f05%252fidentity%252fclaims%252fnameidentifier%3dRESTClient%26http%253a%252f%252fschemas.microsoft.com%252faccesscontrolservice%252f2010%252f07%252fclaims%252fidentityprovider%3dhttps%253a%252f%252ftwo10na.accesscontrol.windows.net%252f%26Audience%3dhttp%253a%252f%252flocalhost%253a50865%252f%26ExpiresOn%3d1339758203%26Issuer%3dhttps%253a%252f%252ftwo10na.accesscontrol.windows.net%252f%26HMACSHA256%3dF4DOJezHyjMpNiC%252fC1vFSS3v3ITFcy6SXyGoT1Zv8ZI%253d&wrap_access_token_expires_in=600

We then URL decoded the response and split out the actual content to get a token like this:

http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=RESTClient&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2ftwo10na.accesscontrol.windows.net%2f&Audience=http%3a%2f%2flocalhost%3a50865%2f&ExpiresOn=1339758203&Issuer=https%3a%2f%2ftwo10na.accesscontrol.windows.net%2f&HMACSHA256=F4DOJezHyjMpNiC%2fC1vFSS3v3ITFcy6SXyGoT1Zv8ZI%3d

This MSDN page gives us the anatomy of a SWT token from ACS. It is essentially a set of key/value pairs separated by the ampersand ('&') character. The keys and values are separated by the equals ('=') character. We also learn that our token contains four mandatory parameters:

  • Issuer
  • Audience
  • ExpiresOn
  • HMACSHA256.

It will also contain any claims we have configured ACS to send us as more key/value pairs. If the claim contains more than one value they will be separated by the comma (',') character.
With this knowledge we are able to dissect the token. Notice that each individual parameter is also URL encoded.
 
Now that we have each parameter as a variable we can validate the token and process it's claims. We can encapsulate the data we have parsed into a class like this. Notice that the expiresOn parameter is in Unix time so we need to calculate the seconds since the epoch to get a DateTime object.

Validating the token

There are four things we should probably validate to ensure our token is authentic.
  1. Has the token expired?
  2. Is the signature valid?
  3. Do we trust the issuer?
  4. Are we the expected audience?
Let's add a static Validate method to the SimpleWebToken class to do this:

Validating expiry, issuer and audience is very simple to do but checking the signature is more difficult. I've added three more methods to help do this.

To validate the signature we need to generate a new signature using a trusted signing key. If this signature matches the issued signature in the token then we know that they were both generated using the same key, and therefore we can trust that the token was issued from where we think it was. This also gives us some guarantees that the token hasn't been tampered with over the wire.

StringToSign reconstructs the token and gives us the parts that we need to include in the hash. ComputeSignature creates the hash using a given signing key and CheckSignature compares the computed signature with the issued one.

By calling the Validate method we are able to determine the authenticity of an SWT token.The next step will be to use these utilities in a Relying Party and authenticate/authorise a client presenting this token. This will be covered in Part Three.

No comments:

Post a Comment