A Federation Swiss Army Knife -- OpenID, FB, & OAuth to SAML & WS-*

Imagine you have a scenario where you want to authenticate end users to your Web site with a consumer-grade authentication protocol like OpenID, OAuth, Facebook Connect, etc. from many different Identity Providers (IdPs). Also, suppose you need to SSO from your site to another or you want to invoke a partner's Web service that requires calls to be secured w/ a WS-Security token. For instance, imagine you have an e-commerce Web site. To increase engagement, conversion rates, yadda yadda, you want to allow customers to login w/ their Twitter, Yahoo!, Facebook, or Google accounts. When a user posts a question in your forum, which you've outsourced to a third-party, you need to SSO to that partner's site which exposes a SAML endpoint. Imagine you also want to publish the user's activity in the forum to one or more of their social networks. Tall order! How might you accomplish this? been wondering this, and here's idea.

My solution leverages PingFederate and Gigya Connect (both of which are sold by companies I'm affiliated w/). Gigya Connect is used as an abstraction that hides all the IdPs and provides a unified representation of a customer. PingFederate marshals this abstract notion of the user into a SAML, WS-Federation, or WS-Trust message for SSO purposes. From a high level, we have this:


In the sketch, I am trying to show how each of the IdPs sends their own types of tokens (TT, TY, TFB, TGOOG) to Gigya which normalizes it into a Gigya token (TG). When the Web app receives this, it can send user-related info to PingFederate, and it sends a SAML message (TSAML) to the partner (i.e., the Service Provider or SP). At the SP, it can use the Gigya API and the user's ID passed in TSAML to publish activity back to Twitter, Google Buzz, FB, etc. Sounds easy when I write it all out like this, but the devil's certainly in the details on this one.

To make this work, I started w/ the HTML doc I wrote after chatting w/ David Brisebois on Twitter the other day. Literally, all I had to change was the location the form was submitted to (nice!):

    Please Sign In using one of the following providers:


If you look at the whole doc, you'll see in the JavaScript that I dynamically added each of the Gigya user object's properties to the form that is being submitted to the highlighted URL. That is a special PingFederate endpoint that instructs it to start an SSO transaction.

Here's the magic:
PingFederate can't make sense of the Gigya user data, so I used its SDK to create an adapter that converts it into something it can understand and will put into a SAML assertion. The code basically loops over the form parameters dynamically added to the request in the JavaScript and hands them back to PingFederate in code like this:

public class AuthenticationAdapter implements IdpAuthenticationAdapter

More Here