Identity Broker: An SSO Protocol Transition From OpenID Connect To WS-Federation
I’ve been building up to more complex federation use cases over the past year. In previous posts, we explored the details of OpenID Connect(OIDC) and WS-Federation (WS-Fed). In those posts, we covered basic scenarios of how to use each protocol to integrate one Relying Party (Service Provider, Client,etc) and one Identity Provider(IdP), generally. There are plenty of small differences between the various identity specs (OIDC, WS-Federation, SAML Browser Profile, etc), but they each rely on trust established through key pieces of meta-data (audience, scope, key material) and digitally signed (and optionally encrypted) tokens (JWT, SAML2, etc). Now, we are going to combine multiple layers of federation relationships using multiple protocols to build a more advanced use case.
Before we go any further, let’s run through a couple of assumptions:
- Does everyone need to know all the details described in this blog post? Absolutely not. If you are curious, by all means, read on. If not, maybe the Microsoft link I reference below or some of my other posts would be more relevant to you.
- Not every aspect of this scenario is explicitly defined by specifications. I fill in blanks as necessary. I try to call these out where I am doing so — more on that below.
Let’s borrow generously from one of Microsoft’s more interesting examples. In that article, you can see two IdPs participating in a WS-Federation-based federation relationship. You can also the more traditional federation relationship between the SaaS application and the Resource Partner’s IdP (ADFS) using OpenID Connect. So, there are two federation relationships occurring concurrently in this use case: one OIDC, one WS-Federation.
From the perspective of the SaaS application, the user is initiating a Service Provider (SP) initiated Single Sign On request. This is the typical use case for OpenID Connect. From the perspective of the Resource IdP, it is acting as an OIDC OpenID Provider and as a WS-Federation Relying Party. The Requestor (User)IdP is acting as a WS-Federation Identity Provider that authenticates users against a User Repository (probably LDAP or Active Directory). I did this very thing for a client about a year ago. It is fairly common in the Microsoft world (Azure Active Directory and ADFS).
Instead of SaaS Provider, we’ll use the terms Resource (or Service) Provider and Service Provider Organization. Instead of “Customer”, we’ll use the term User Organization.
Call me unoriginal, but this post is going to explore essentially the same use case, but go into more detail about the exact steps the browser takes to do the redirect acrobatics necessary to implement the protocol transition that occurs at the Resource Provider’s IdP. In the WS-Federation spec’s nomenclature, the role of the Resource Provider’s IdP in this scenario is that of an Identity Broker. This could also be referred to as an Identity Bridge or just a really complicated federated identity use case.
What is the advantage of doing it this way? It gives the Resource Provider organization that owns the Resource Provider (SaaS application in the original article) a mechanism to support a wide variety of different identity integration scenarios. It abstracts the complexity that comes with this sophisticated toolset away from the application platform. It abstracts the end user’s credentials (password, etc) away from the Resource Provider; in other words, the systems that the Customer’s (User’s) organization has no control over, never sees the end user’s credentials.
In the following diagram, I have a superfluous reproduction of the work done in the original article I referenced. Though, here I am making it a bit more generic.
If we add some details, we get the following diagram. It is important to remember:
- The OpenID Connect Authorization Code Flow is used for the federation relationship between the Service/Resource Provider and Resource IdP.
- The WS-Federation Passive Requestor protocol is used for the federation relationship between the Resource IdP and User IdP.
- I skipped the Home Realm Discovery Endpoint interaction on the User’s IdP. Most IdPs will have a parameter that can be passed to the WS-Federation SignOn Endpoint that will specify a realm.
- The WS-Federation Application Service Endpoint and WS-Federation Passive Requestor SignOn Endpoint could be the same endpoint where distinct endpoints are specified through the wa field.
- The OIDC and OAuth2 specs do not define how the OAuth2 Authorization Endpoint authenticates the user — HTTP Redirect to a login workflow, serving a login page directly, etc. In the following diagram, the Resource IdP Authorization Endpoint, does a redirect to the User’s IdP WS-Federation Passive Requestor Signon Endpoint.
- The WS-Federation spec does not define how the WS-Federation Application Service Endpoint returns the user to the OIDC Authorization Endpoint to complete the original signon transaction. In this example, we assume that the IdP can track the wctx field from the original redirect that initiated the WS-Federation signon transaction and can redirect the user-agent to the Authorization Endpoint with the original parameters.
- Although not depicted in the following diagram, the User IdP performs an LDAP simple bind or similar operation to authenticate the user against the User Repository.
- How the WS-Federation Passive Requestor SignOn Endpoint authenticates the user is not explicitly defined. In this example, the endpoint redirects the user to a Login Workflow Endpoint on the User’s IdP.
- In this example, the login workflow redirects the authenticated user back to the WS-Federation Passive Requestor Signon Endpoint in order to have the security token generated and returned to the Relaying Party (Resource IdP). The Login Workflow could also have returned the security token directly.
The following steps are outlined in this diagram.
- The User Agent sends request to Service Provider URL.
- Either the user clicks a login link provided by Service Provider or SP automatically redirects to Resource IdP’s Authorization Endpoint (initiating an OIDC login sequence with the Authorization Code Flow).
- The IdP detects that this application’s (client, RP) users should be authenticated by a remote Identity Provider via a WS-Federation relationship and redirects the user to the User IdP’s WS-Federation SignOn Endpoint (ie, the WS-Federation Passive Requestor Endpoint).
- The User IdP detects that the user has not yet been authenticated and sends the user to the login workflow. The user provides credentials and successfully authenticates against the User IdP.
- The User IdP redirects the user back to the WS-Fed SignOn Endpoint. This time, the user has an authenticated session. A WS-Federation protocol response is generated as described here and embedded in a redirect back to the Resource IdP’s WS-Federation Application Service Endpoint.
- The WS-Federation response message with security token (probably a SAML assertion) is sent to the Resource IdP’s WS-Federation Application Service Endpoint as the value of the wresult parameter via a hidden form submission as described here. The security token (from the User IdP) is validated and an authenticated session is established for the end user. In this way, the Resource IdP is acting as a Relaying Party of the User IdP.
- The Resource IdP redirects to the (original) OIDC Authorization Endpoint (this time with an authenticated session represented by a session cookie). The authenticated user can now have an authorization code returned as part of a redirect to the registered redirect URI.
- The authorization code is submitted to the redirect URI that is advertised on the application.
- The application (ideally, using an OIDC authentication library) passes the authorization code to the Resource IdP’s Token Endpoint. The application’s client credentials (client_id + client_secret are validated) and the user’s authorization code is validated. If all is valid, then a standard OAuth2 Token Endpoint Response is returned with an ID Token, access token, and refresh token.
- If the application needs additional information about the user, it can make a call to the Resource IdP’s UserInfo Endpoint.
In my next post, I am going to revisit the exact same use case, but use OpenID Connect in both layers of federation relationships.