External Authentication Configuration for Embedded Applications

External Authentication Configuration for Embedded Applications

Since 5.1.0

Overview

When integrating the application as an embedded component, the host system can provide its own authentication context instead of using the application's default authentication mechanism. This document explains how to configure and implement external authentication.

In this way your host application can obtain the same user context in the integrated system.

Requirements

The application requires a function that can provide valid authentication tokens. These tokens are typically obtained through machine-to-machine (M2M) connections, such as token exchange mechanisms.
The minimal required response format is:

{ access_token: "eyJhbG..." }

Currently, only the access_token field is mandatory. The application will automatically request a new token when the current one expires.


For future compatibility, the authentication system supports a more comprehensive payload structure:

{ access_token: "eyJhbG...", expires_in: 7200, refresh_expires_in: 1800, refresh_token : "..2rgOShce-sA\", token_type: "Bearer", not-before-policy: 0, session_state: "25127dc7-315b-4fb5-9bb5-625ff09e1b29", scope: "email profile security-schema", contentType: "application/json" }

FMA in the “external auth” mode will request a new token automatically as soon as the one in use expired.

Please set a reasonable expiry time on the token. FMA assumes a token needs to be replaced if its validity period is below 15 seconds. Higher expiry values will also reduce a number of complex authentication calls made by the system.

Implementation Guide

Preventing Default Authentication

To prevent the application from launching with its default authentication service redirect, initialize it with the awaitConfig parameter:

https://localhost:8080/client/?awaitConfig=true

This will perform basic initialization while waiting for your custom configuration.

Configuration Setup

The application exposes a global promise hdcReadyForConfig that signals when it's ready to receive custom configuration. You can access this promise using the following pattern:

if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { window.hdcReadyForConfig.then(() => { // Safe to proceed with your calls here console.log('### Ready for Config'); }); }); } else { window.hdcReadyForConfig.then(() => { // Safe to proceed with your calls here console.log('### Ready for Config'); }); }

Once the promise resolves, you can configure the application and start it using:

hdcAppStarter.start();

Example Implementation

This implementation demonstrates setting up an asynchronous token provider that your host application can use to supply authentication tokens to the embedded application.

//token defined inline only for testing, should be obtained from your backend const myToken = {access_token: "eyJhbGciO…"}; //sample async function that will fetch the token window.getExternalToken = function() { return new Promise((resolve) => { //Small delay to simulate async setTimeout(() => { resolve(myToken); }, 100); }); } //use hdcAuth object to set a function for fetching external auth tokens if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { window.hdcReadyForConfig.then(() => { // Safe to proceed with your calls here hdcAuth.setExternalAuthFunction(getExternalToken); hdcAppStarter.start(); }); }); } else { window.hdcReadyForConfig.then(() => { // Safe to proceed with your calls here hdcAuth.setExternalAuthFunction(getExternalToken); hdcAppStarter.start(); }); }

 

Embedding in iFrame

When host system is using an iFrame to embed our application, a direct code execution might not be allowed inside of the frame scope. In that case systems can communicate via messages.

A host system messages handling should implement subscription to messages:

const getExternalToken = async () => { // Your token acquisition logic }; window.addEventListener('message', async (event) => { if (event.data.type === 'HDC_APP_READY_FOR_CONFIG') { // Send token when requested const iframe = document.querySelector('#your-iframe-id'); iframe.contentWindow.postMessage({ type: 'HDC_START_APP' }, '*'); } else if (event.data.type === 'HDC_AUTH_TOKEN_REQUEST') { const token = await getExternalToken(); iframe.contentWindow.postMessage({ type: 'HDC_AUTH_TOKEN_RESPONSE', token }, '*'); } });

For the full working sample, please access this address on your instance (replace localhost with your instance): http://localhost:8080/client/messageAuthTester.html

This example is using FMA anonymous auth token service that must be enabled for this test to work. Its not intended for production use and should be replaced by a proper backend logic for fetching a token between your backend system and FMA auth server.

In order to implement that, create a machine2machine client and use “token exchange” in order to obtain a valid token for your user.

Summary of the most important steps showcased in the messageAuthTester.html:

  1. Setup environment for FMA app:

    1. create an iframe element for FMA app

    2. implement fetchTokenForHdc- this function should make an API call to your backend (not FMA) to fetch a token for your user

    3. implement message subscription to listen for events from FMA app

  2. when your page is ready (e.g. after DOMContentLoaded event), initialize a message handler (window.addEventListener('message', async (event))

  3. Load the FMA app in the iframe, make sure that the url contains a query parameter: ?awaitConfig=true

  4. await message: HDC_APP_READY_FOR_CONFIG, send config messages and start the app:

    1. HDC_ENABLE_EXTERNAL_AUTH

    2. HDC_START_APP

  5. be ready to handle message: HDC_AUTH_TOKEN_REQUEST

    1. respond with HDC_AUTH_TOKEN_RESPONSE

    2. your system should respond in max 20 seconds

Related content