A question that has been coming up a lot lately is how does one send a SAML bearer token to downstream WCF service? In each of the recent cases, a front-end app was being presented with a token that it needed to convert to SAML before calling the back-end service. To do this, the Web app would send the incoming token or some other credential to an STS, get the SAML token back, and include it in its request to the next service as shown in the following sketch:

token_translation2.png

To create such a system using .NET requires certain config on the client and server, so I'll enumerate what's required on each. At the end of this post, you'll find links to other blog entries w/ more detail and a link to download a sample project.

Web Service Client


Web Service

  • Use the WS2007FederationHttpBinding binding w/ transport security (as in the client)
  • Like in the binding of the client, set the Message.IssuedKeyType to SecurityKeyType.BearerKey
  • Make sure it's expecting the assertion to be signed by the cert of the STS (by wiring up an IssuerNameRegistry that will check)
  • Configure the audience restriction to be the same one included in the SAML assertion
If you're self-hosting your WCF service on Windows 7, check out this write up from Aviad P. about using netsh to configure HTTPS. (This was the part of all this that took the longest for me. Grr!)

If after reading the above, things aren't quite clear yet, check out these blog posts for more details:


If you're still stuck, have a look at this sample (licensed under the GNU GPL), leave a comment here, and/or email me.

Last Monday, AT&T announced that they have launched a new API platform. As I wrote about on Kin Lane's API Evangelist blog, the PaaS includes various components to help developers quickly build and launch new applications. One of these is an HTML5 SDK that simplifies what mobile Web application developers have to do to securely call the mobile network operator's new cloud services.

The carrier is securing their API with OAuth 2. They support both the authorization code and client credentials grant types defined by that spec. att-oauth2.gifThey also allow users to authenticate to the Authorization Server (AS) w/ a username/password, a MSISDN and a PIN, or by simply being connected to their network. Also, each of the services has a different scope. To get approval to use them, the app developer includes these when redirecting the subscriber to AT&T's AS.

The various authentication mechanisms are interesting, but what's even more intriguing to me is a Sencha Touch plug-in that is included w/ the SDK and how it works in tandem w/ a proxy. The plug-in exposes a JavaScript object model for the new cloud services that works naturally w/ this popular toolkit. Extending Sencha Touch like this allows developers who are already using that framework to quickly integrate the carrier's new services. For others that are not, it allows them to build UIs that look and feel like native apps on various mobile platforms while simultaneously simplifying the use of AT&T's API. To see how, let me explain how the Sencha Service Access Layer (SAL) works w/ the proxy.

att-paas-arch.pngAs shown in the following figure, all requests to the AT&T cloud go through an intermediary. This proxy is hosted by the same developer as the HTML5 app. The first time a user invokes the application, it will call the proxy which will find that it doesn't have an OAuth Access Token (AT) or Refresh Token (RT). For this reason, it will return an error rather than calling the carrier's cloud service. The Sencha plug-in will catch this and pop up an IFRAME displaying AT&T's OAuth AS. (The samples don't display the address, but I would.) The user will authenticate as described above, and the AS will redirect the IFRAME to the callback handler which is hosted on the same server as the proxy. It will exchange the Access Code (AC) provided on the query string for an AT and RT. These will be persisted in a session. Subsequently, when methods are called on the plug-in, a request will be made to the proxy, the session will be used to find the AT, and the proxy will tack it onto the request that it forwards to AT&T.

This new API and its SDK provide an innovative way of using OAuth that simplifies the work that mobile Web application must do. The docs were great, the samples were very helpful, and I quickly figured out how to use the toolkit. I also found it interesting that a helper was used here to aid in securely consuming services from mobile apps as I've talked about doing for other use cases.

If you have questions or thoughts about this or the other blog post I wrote about this new API, please feel free to lave a comment here or drop me a note.
Here's the scenario: You're creating a .NET app that uses active federation to get a token from an STS and submit it to a downstream service. That other service might be another STS or it might be a Web service written in .NET or some other language (doesn't matter). The token that you're getting from the STS is a bearer token. You have some code like this:

private static void CallWebService(SecurityToken token)
{
    var factory = GetServiceChannelFactory<IFoobarService>();
    var channel = factory.CreateChannelWithIssuedToken(token);

    var order = channel.DoFoo();
}

When the call to DooFoo is made, you get an error like this:

The signing token Generic XML token:
   validFrom: 01/07/2012 09:33:36
   validTo: 01/07/2012 10:03:36
   InternalTokenReference: Saml2AssertionKeyIdentifierClause( Id = 'U8ovpOcJlJFu7udUreVI_4I69vj' )
   Token Element: (Assertion, urn:oasis:names:tc:SAML:2.0:assertion)
 has no keys. The security token is used in a context that requires it to perform cryptographic operations, but the token contains no cryptographic keys. Either the token type does not support cryptographic operations, or the particular token instance does not contain cryptographic keys. Check your configuration to ensure that cryptographically disabled token types (for example, UserNameSecurityToken) are not specified in a context that requires cryptographic operations (for example, an endorsing supporting token).

To fix this, do two things:

  1. Make sure the binding you're using for the service (not the STS, that doesn't matter) is WS2007FederationHttpBinding not WS2007HttpBinding or WSHttpBinding.
  2. On that binding, set Security.Message.IssuedKeyType to SecurityKeyType.BearerKey.

Error goes away and now you can fix the next problem ;-)

So, what was the deal? The token you had in hand was a bearer token, meaning there is no requirement on the presenter when submitting the token to prove that it was indeed the entity that got the token from the STS; however, in its default configuration, WCF is trying to do just that. Because the token doesn't have a proof key in it (the cryptographic key the error is talking about), WCF can't compute the digital signature it thinks it should send along.

Alternatively, if you really do want to prove to the RP Web service that you were the one who got the token from the STS, ask for a Holder of Key (HoK) assertion. You can do this by changing the TokenType in the RST, but your STS will have to support this.

If you have questions on this, leave a comment below or shoot me a mail.

I got an email the other day from Pedro Félix, asking for my thoughts on an OAuth scenario that he was wondering about and discussing with Howard Dierking. As Pedro and I talked, I learned that he had a really interesting problem on his hands. Basically, he wanted to create an OAuth 2.0 protected service that called an OAuth 1.0a protected service (e.g., Twitter). So, what he had on his hands was a bunch of clients, tokens, services, and two different protocols that do things similarly but w/ slightly different names. Very confusing stuff.

To begin making sense of all this, it's helpful to list out what we know:

  • Pedro wants to call the Twitter API from his own API.
  • The Twitter service is an OAuth 1.0a Resource Server (RS).
  • Twitter has an OAuth 1.0a Authorization Server (AS).
  • The Twitter service naturally only trusts it's own AS.
  • Pedro's service is an OAuth 2 RS and an OAuth 1.0a Twitter client.
  • Pedro has an OAuth 2 AS.
  • Pedro's service naturally only trusts his own AS.
  • The Web app that calls Pedro's service is an OAuth 2.0 client and must submit Access Tokens (ATs) emitted by his own AS (not Twitter's) when calling his service.
  • The Resource Owner (RO) is a Twitter user and will authorize Pedro's service to call the Twitter API to modify their data.
  • The RO authenticates to Pedro's AS using Twitter's OAuth 1.0a AS.
  • Pedro's AS asks the RO to authorize the third-party client to access his service which in turn will access Twitter's.

With these basics in mind, have a look the the following picture that presents an overview of the actors involved:

oauth-to-oauth2.gif


Now, to get an idea of how Pedro's service would call Twitter's, flip through animations in the following slide deck.

See how one OAuth protected resource can call another? Pretty cool stuff! It's also cool that if instead Pedro wanted to call the Facebook graph API which uses OAuth 2, it would work almost the exact same way. As if that we're cool enough though, what's even cooler is that this isn't just theory. I was able to implement this in PingFederate in about half the time it took me to write this blog post! If I have some time over the weekend when I'm not celebrating my little one's second birthday, I'll try to post a screencast.

Anyway, thanks Pedro and Howard for inviting me into your conversation. If you or anyone else has questions about this or other OAuth matters, please feel free to post a comment here or send me a mail.
The other day I wrote about a way to use OAuth w/ mobile apps that was not susceptible to phishing and does not use the password anti-pattern. I just had to code it up and make sure it worked. What better time then 4 AM when the house is quite? Ah, jet leg ;-)

Using Lars Vogel's tutorial on C2DM, PingFederate's new OAuth server, and a little Python Web app running on CherryPy, I found that it does actually work! Here's the high-level points to be aware of if you want to implement this:

  • The C2DM API is in beta, and you'll need to sign up for access using a Google account. Developer accounts have a limited quota.
  • You need to provide the email address you sign up w/ and a password to the Google ClientLogin service to get an OAuth-like Access Token (AT). You don't have to use your own password though; you can create one specifically for this purpose (which you'll have to do if you're using 2FA w/ your account like I am).
  • These tokens need to be renewed every so often, so, in your Web app, keep an eye out for errors. (It's not indicated by the HTTP status code but the contents of the body IIRC.)
  • PingFederate's OAuth token endpoint is configured w/ a self-signed SSL cert by default, so you'll need to work around that during development.
  • There can be a bit of leg between the time you publish the OAuth Access Code (AC) and the time your app gets the message. Meanwhile, your user will be looking at a blank white browser window. To avoid this second or so delay, you can register a customer scheme in your app. Then, in the helper Web app, return a 302 to that as soon as you send the AC to the Google C2DM service. This will cause the app to come to the foreground immediately. Alternatively, put a little spinner in the Web page.
That's basically it. If you follow Lars' tutorial and keep these things in mind, I'm sure you'll be up and running in no time -- especially if you've woken up before anyone else and it's really quite out ;-) Here's a little demo of it running that will hopefully motivate you to get it coded up too. If you get stuck, drop me a note.