January 2012 Archives

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.

Tons of passwords are an unfortunate reality. I'm working hard every day to reduce the number of passwords that we have to use around the Web. Till it gets to a management number though, we need a way to cope. Everyone has a technique -- some put their passwords in a spreadsheet, others write them on post-its stuck to their computer screen, others use the same password(s) everywhere, some use a password manager in their browser. All of tese techniques have various security implications, however. We have to manage this chaos some how though, so the security issues are often disregarded. Is there a more secure way?

A better alternative would be one that doesn't require you to write anything down, isn't locked away in a computer that you don't have ready access to, and is unique per site and per account. One such technique is to create a set of steps, an algorithm, that you follow to create a unique password for every user account on every site that requires one. To do this, start by using something from the Web site that won't change, like the name; this is your "seed" value. For instance, your algorithm could be something like this:

  1. Capitalize the first letter of the Web site's name and make the rest lowercase.
  2. Take the first 4 characters of this name. If it is less than four characters, add underscores to make it at least four characters long.
  3. Add some word that contains a symbol and a number and is easy to remember (e.g., P@nda1). The result is the password to use on the site.

So, using this sample algorithm, the password for CNN would be this:

  1. Cnn
  2. Cnn_
  3. Cnn_P@nda1

For Spotify, it would be this:

  1. Spot
  2. Spot
  3. SpotP@nda1

The result is a strong passwords that while difficult to remember is easy to reproduce because the necessary steps are memorable. There's a problem w/ this though. If a baddie ever sees just two of your passwords, they'll have a very easy time guessing any of your others because they are so similar. So, here's an easy fix that makes things more secure

Download an app to your phone that can generate a password from an input phrase. This app should produce the same password every time it's given the same input. It should produce passwords that includes uppercase, lowercase, numbers, and symbols. This app should not have permission to access the Internet. Some of the free ones require it, so they can download ads. Who knows though? They might also be uploading your passwords. An example of a good one for Android is Password Generator Pro.

Now, when you have to sign up for a new account and create a password, use your algorithm as described above. However, don't use that as the password. Instead, use it as input to the app. This will produce a random password from a phrase that's hard to guess but associated to the site you're visiting. With the the site-specific "seed," the common algorithm, and an app that's running on your phone which generates strong passwords, you'll have a pretty easy system for managing the chaos where you don't have to write anything down, each password is unique, and they can't be guessed.

Make sure you don't let people know your algorithm though or all this security breaks down.

If you have a better way to manage this mess or if you think there are issues w/ this system, leave a comment here or drop me a line.

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.