This project provides a solution for offloading Single Sign-On (SSO) authentication flows from a sandboxed client environment (like an Isolated Web App or a Chrome App) to a dedicated Chrome Extension helper.
It consists of two main parts:
SSO offloading extension: A Chrome Extension that processes the authentication flow in a separate, top-level tab.
SSO Offloading Connector: A TypeScript module used by the application to intercept auth requests and delegate them to the offloading extension.
The SSO Handler is a background service worker that acts as a trusted helper for processing authentication.
- Listens for Requests: It listens for external messages from trusted applications using
chrome.runtime.onMessageExternal
. - Validates: It checks if the request is from a allowlisted origin and that no flow is already in progress for that origin.
- Opens Auth Tab: Upon receiving a valid
sso_request
, it opens the provided authentication URL in a new, focused browser tab. - Monitors for Redirect: It watches the tab for navigation. When the tab's URL matches the
redirect_uri
specified in the initial request, it knows the flow is complete. - Returns Result: It captures the final redirect URL (containing the authorization code or tokens) and sends it back to the application in a
success
message. - Handles Cancellation: If the user closes the authentication tab manually, it detects this and sends a
cancel
message back to the application. - Cleans Up: After the flow succeeds, fails, or is canceled, it closes the auth tab and cleans up all listeners.
This is a TypeScript module designed to be used within an Isolated Web App or a Chrome App. It intercepts authentication requests and offloads them to the SSO offloading extension. It works with both the IWA's <controlledframe>
and the Chrome App's <webview>
.
- Creation: Create a connector instance using the
createSsoOffloadingConnector
factory function. It requires the offloading extension's ID, a reference to the target view element (<controlledframe>
or<webview>
), and URL filters. Optional parameters includeonInterceptError
callback that will be run by the conenctor when any error occurs during offloading flow. - Handshake: The
start()
method first "pings" the extension with aping
message to ensure it's installed and active before proceeding. - Listening: If the handshake is successful, it attaches a request listener to the target view element using the appropriate platform API.
- Interception & Delegation: When a navigation request inside the view matches the URL filters, the connector cancels the request and sends the intercepted URL to the offloading extension in an
sso_request
message. - Redirection: The connector waits for the extension to send back a
success
message containing the final redirect URL. It then programmatically sets the view'ssrc
attribute to this new URL, completing the authentication flow within the application. - Cleanup: The
stop()
method removes the event listener and ceases interception.
import { createSsoOffloadingConnector, SsoOffloadingConnectorError } from 'sso_offloading_connector';
// Get a reference to the <controlledframe> element (or <webview>)
const cfElement = document.getElementById('auth-cf'); // Can also be a WebView element.
const SSO_EXTENSION_ID = 'abcdefghijk1234567890'; // The ID of SSO offloading extension
const requestFilter: RequestFilter = {
urls: ['https://accounts.google.com/o/oauth2/v2/auth*','https://sso.mycompany.com/*'], // Intercept all requests to these domains.
};
const onInterceptError = (error: SsoOffloadingConnectorError): void => {
console.log("Error occured :(, "+ error.name +": "+ error.message);
}
// Create connector instance
const ssoConnector = new SsoOffloadingConnector(
SSO_EXTENSION_ID,
cfElement,
requestFilter,
onInterceptError
);
// Start offloading SSO calls for the cf.
ssoConnector.start().catch(...);
// Stop the connector if no longer needed.
ssoConnector.stop();
- Build
# Build the core SSO Connector and offloading extension
npm run build
# Build the Chrome App example
npm run build:chrome-app
# Build the Isolated Web App (IWA) example (optional, .swbn can be downloaded from this repo, bundle id: yr57inu2f27fji2d2xd2lj7fjt3scdhby3bs7s4vdxh3rrujkdnaaaic, version 1.0.0)
# Note: This may require a pre-generated key.
npm run build:iwa
-
Packaging and force-installing extension (and Chrome App example) This project uses the localExtensionHost tool to package and host locally the offloading extension and Chrome App. Mentioned repository contains detailed instructions on this step, including how to force-install packaged projects for ChromeOS.
-
Force - install IWA IWA bundle (
.swbn
file), as well as itsupdate_manifest.json
file, needs to be hosted and then the app has to be force-installed viaIsolatedWebAppInstallForceList
policy. Getting started with Isolated Web Apps article for reference. -
Test time!
This is not an officially supported Google product. This project is not eligible for the Google Open Source Software Vulnerability Rewards Program.