Fedeated widgets

The concept of Federated Widgets consists of four parts:

  • Main site
  • Federated Widget
  • Popup loader
  • Hidden iframe loader

Loading a javascript single-page application with federated login as a widget (iframe) into a container page (main site) is very useful. It may sound like a trivial task, but it is really not.

This article describes one way or approaching this concept in a way that treats the user well, and makes use of various tweaks of web technology / javascript,

Some of the features of this flow:

  • Will allow you to be automatically signed in to the widget if you have a signle sign-on session at the IdP
  • Will not reload the widget at any time after the first load. Neigther when using the popup loader or the hidden iframe loader. Smooth!

At the initial page load of the main site, this is the overall flow:

  • Main site loads
  • Federated Widget loads within, and requires the user to be authenticated in order to present the content.
  • Federated Widget checks for cached OAuth 2.0 tokens, if an cached OAuth 2.0 token was found, then:
    • Use the access token to perform a CORS request to the userinfo endpoint.
    • Validate the response, and the user is now authenticated.
  • If no token was cached, fire up the hidden iframe loader and prepare it with an OAuth 2.0 authorization request, or even better an OpenID authentication request. The most important part is to indicate the passive mode, using in example: prompt=none.
    • detect when the hidden iframe returns to the passive callback redirect_uri. If successfully store the obtained token.
    • Validate the response, and the user is now authenticated.
    • Use the access token to perform a CORS request to the userinfo endpoint.
    • Validate the response, and the user is now authenticated.
  • If the user is not already having a single sign-on session at the identity provider, or somehow needs to interact with the identity provider (grant, consent or similar) the passive authentication request will fail. And then we fill the whole widget with information to the user that the user would need to authorize the widget to make it work. Like this:

  • When the user clicks authorize, then open a Popup loader window. Load an authorization request in that window, and set the redirect uri of that request to point to the popup redirect_uri. The popup may look like this:

  • When the user returns to the popup redirect_uri within the popup loader window, its script will automatically close the window. The federated widget will detect this and pick the popup.location.href (url) of the popup window. It will look for an oauth token in that response. If there is a valid token:
    • Use the access token to perform a CORS request to the userinfo endpoint.
    • Validate the response, and the user is now authenticated.
  • User should be successfully logged in to the widget, in a trusted way, without interferring with the main site.

The redirect_uri pages

You would typically need three different redirect_uri-s.

Regular redirect_uri

The regular redirect_uri typically points to the federated widget it self. It is not used in this basic user flow, but it might be used

Passive callback redirect_uri

The passive callback redirect page is simply a blank page. Something like this:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title>Passive Callback</title>
</head>
<body>
</body>
</html>

Popup redirect_uri

An empty page, similar to the passive callback redirect_uri, but with a simple onload script that calls a function popupCompleted() at the opener window, the federated widget.

<script type="text/javascript">
	window.onload = function() {
		window.opener.popupCompleted();
		setTimeout(function() {
			window.close();
		}, 200);
	};
</script>

TBA