Embedding Web phone

General

When the webphone is embedded inside another web application, it can be done in two ways:

  1. Load the code in the parent page and render the custom <webrtc-client-ui /> directly

  2. Render an <iframe /> containing the phone on the parent page

The first approach is used in the stand-alone webphone https://phone.enreachvoice.com

When embedding to the other external system, the second method is usually used.

Note that refreshing page having webphone embedded, will disconnect all ongoing calls and forces re-login.

Check https://gitlab.com/benemen/public/webrtc-samples for tampermonkey demo scripts for how to use webphone JavaScript API, including how to use different login methods.

Authentication

Webphone can authenticate user with following methods:

  • Classic username & password authentication

  • Modern OAuth2/OpenId Connect based authentication. Recommended!

  • Impersonation token authentication

Classic username and password authentication

The default option is to display a login form in which the user enters a username and password. Webphone does authentication to REST API with entered details.

This is the easiest option to get started with embedding webphone development, but is not often usable in real production use.

Username and password authentication can also be done using Javascript API method loginUsingUsernameAndPassword()

 

Modern authentication

The preferred option for authentication is to use OAuth2/OpenIdConnect based authentication via Enreach Identity.

Enreach Identity works in two modes:

  • Local identity provider mode

    • The password of the user is stored in Enreach Identity

    • When a user is authenticating, login form is shown from https://id.enrachvoice.com

  • External identity Provider mode

    • Identity is integrated with an external Identity provider

    • When a user is authenticating, the login form is shown from the external IdP

Currently, Enreach Identity can be linked to Microsoft Entra ID (formerly known as Azure AD). This enables a seamless Single Sign-On experience for organizations using Microsoft 365 services.

 

 

Impersonation token-based authentication

There is also an option to use https://doc.enreachvoice.com/beneapi/#impersonation. In this scenario, a separate backend integration is required. This backend service must have a separate API account with impersonation permission for all agents. When a user needs to log in to the webphone, the backend service retrieves an impersonation token for a user, and the webphone uses this token to access EnreachVoice core services as an end user.

Impersonation permissions are very powerful. Extra caution must be taken when securing the backend API account and authenticating users.

This approach is not recommended for new implementation.

Modern authentication requirements

In all embedding cases, proper ClientId must be provisioned on the Enreach Identity.

By convention, clientId is the fully qualified domain name (FQDN) of the web application.

ClientId configuration to Enreach Identity is done by the Enreach Delivery team.

Authentication flow handling

The simple way to log in is to use webrtc.loginUsingSSO("user.name@anything.com"). This is, however, usually undesirable in embedding context, because:

  • The phone sits in the iframe and cannot do a full page redirect

    • Redirecting inside the iframe does not work when the customer is using an external IdP (Azure) that does not allow rendering the Azure login form inside an iframe for security reasons.

  • Supposedly, we don’t want to do a full page redirect to Enreach Identity on login even if we rendered the phone in the parent context

The solution is to handle the authentication flow explicitly in the parent page (CRM Frontend) context.

 

Enreach Identity is backed by Keycloak and the phone uses the keycloak-js Javascript adapter. The phone also supports passing in a pre-authenticated keycloak.js object.

This enables the parent page to use for example a pop-up window to log in.

High-level flow

  1. Retrieve user authentication information from discovery service

    1. If authority is null -> user is not enabled for Modern Authentication

    2. Otherwise, it points to the authentication realm of the user

    3. If authorityIdPHint is null → user is using local IdP.

    4. Otherwise user is configured to use an external IdP such as Azure

  2. Create keycloak object based on discovery results

  3. Check if SSO-session is already ok

    1. If ok → pass it to the webphone

    2. If not → Open IdP-specific authentication dialog

See reference implementations below

Reference Implementations for Modern Authentication

Voice for D365

The steps of authentication on code level:

  1. Set up Keycloak object:

    1. Query user’s context info from discovery service, to get identity url and idpHint:

      var discoUrl = 'https://discover.enreachvoice.com/api/user/?user=' + username; var discoResponse = await fetch(discoUrl); if (!discoResponse.ok) { var errData = await discoResponse.json(); var errorMsg = ''; for (const key in errData.errors) { errorMsg += errData.errors[key].message; errorMsg += ' '; } throw new Error(`Login process failed with username: ${username}. ${errorMsg}`); } else { discoResponse = await discoResponse.json(); } const data = discoResponse[0]; if (!Object.hasOwn(data, 'authority') || !data.authority) { throw new Error(`Login with SSO not supported. User "${username}" not migrated to Enreach Identity.`); } const identityUrl = new URL(data.authority);
    2. Create Keycloak object
      This snippet creates loginParams and Keycloak objects based on the data received from discovery.
      loginParams object is not used by Keycloak initialization now, but login flow later on.

      loginParams = { loginHint: username, redirectUri: "https://appname.azurwebsites.net/authproxy" }; if (data.authorityIdPHint) { loginParams.idpHint = data.authorityIdPHint; } keycloak = new Keycloak({ url: identityUrl.origin, realm: identityUrl.pathname.split('/')[2], clientId: window.location.host });
  2. Attempt login with check-sso

    1. Initialize Keycloak and do a silent check (check-sso) if a user session is active atm.

      var authenticated = await keycloak.init({ onLoad: ('check-sso'), scope: 'beneapi' });
    2. Pass Keycloak object to WebRTC (see step 6), or open auth dialog if not authenticated

  3. Authenticate within pop-up
    The reason for the need for pop-up (instead of carrying out auth flow in an embedded iframe) is that AzureAD (for security reasons) can’t be loaded within an iframe.

    1. Open pop-up
      Keycloak object returned the login Url in the previous code snippet. It contains the redirect Url as well, passed in the first snippet. The Url returned by keycloak.createLoginUrl() will point to Keycloak server.

    2. Receive response
      Keycloak manages the authentication flow: redirects the user to AzureAD (if necessary), then redirects back to the value pointed by redircetUri param (see first snippet).

    3. Validate response
      The response received in the query string on redirect page needs to be checked: code parameter being present means successful authentication.
      Send a signal to opener page about the outcome of authentication using postMessage mechanism.

  4. Receive postMessage in the parent window
    The parent (opener) window hooks up an event listener when initializing:

  5. If embedded opener page received info about successful authentication (event.data.ok == true), steps 3 and 4 are repeated. Carrying out check-sso again will now return authenticated=true

  6. Pass Keycloak object to WebRTC

Voice for SalesForce

In Salesforce the system controls the iframes (connector iframe, login iframe) from process perspective so the login process with keycloak needs to be handled in it’s own iframe.

  1. In Connector iframe, signal SF to load the login iframe.

  2. Get the Keycloak client-id and username from SF.

  3. Do the discovery to EnreachVoice API and setup Keycloak object

  4. Init Keycloack object with check-sso.

    1. If uthenticated session found => jump to step 5.

    2. If no session found

      1. Show login button which opens popup onclick with login url defined in Keycloak object.

      2. After login the Keycloak redirects user to redirect page defined in Keyclock object.

      3. In redirect page signal Login iframe.

      4. Execute Keycloak init again in Login iframe (step 4).

  5. Signal Connector iframe that user has an active authenticated session.

  6. Connector iframe tells WebRTC (hosted in Connector) to login with SSO.

  7. Signal SF that WebRTC is authenticated when ‘logged-in' event is received in Connector.

 

 

© Enreach, Mannerheimintie 117, 00280 Helsinki, Finland
+358 40 450 3000, www.enreach.fi