Ping SDKs

Creating a custom UI app to share across OIDC apps

Server support:

  • PingOne

  • PingOne Advanced Identity Cloud

  • PingAM

  • PingFederate

SDK support:

  • Ping SDK for Android

  • Ping SDK for iOS

  • Ping SDK for JavaScript

In this tutorial you replace the default PingAM or PingOne Advanced Identity Cloud user interface for authentication with your own custom user interface.

You’ll use an existing JavaScript sample application to act as your custom UI. This app will step through your authentication journeys, and act as the central UI for one or more sample client apps.

Understanding the custom UI flow

When the Ping SDKs perform OIDC login they initiate the OAuth 2.0 Authorization Code flow on your PingOne Advanced Identity Cloud tenant or PingAM server.

Your server would usually use its built-in user interface to authenticate the user, before returning to the client app with the authorization code.

For this tutorial you’ll configure your server to use your custom UI app to authenticate users instead.

Custom UI app in OAuth 2.0 authorization code flow
Figure 1. Custom UI app in OAuth 2.0 authorization code flow

The overall authentication flow is as follows:

  1. In the client app, when the user initiates sign on the client app calls the /authorize endpoint to start the OAuth 2.0 flow.

  2. The OAuth 2.0 client you configure in the server needs to authenticate the user, and redirects users to your custom UI.

    It appends a goto query parameter to the URL, so that the custom UI app can redirect to the server after successful authentication.

  3. The custom UI starts the authentication journey, and steps through each node, handling the callbacks as necessary.

    Note that the custom UI app does not perform any OAuth 2.0 operations itself. Its only role is to authenticate the user by stepping through the journey, and then returning back to the server with the session token, so that the server can continue the OAuth 2.0 flow.

  4. The custom UI app renders the UI to handle any interactive callbacks in the journey. For example, to capture the username and password credentials.

  5. When authentication is successful, the server issues a session token on behalf of the user to the custom UI app.

    The following snippet shows how the custom sample app handles the successful authentication, and uses the goto parameter:

    Excerpt from /javascript/embedded-login/src/main.js
    // Check URL for query parameters
    const url = new URL(document.location);
    const params = url.searchParams;
    const goto = params.get('goto');
    
    const handleStep = async (step) => {
      switch (step.type) {
        case 'LoginSuccess': {
          if (goto != null) {
            // Journey complete
            // Return to server to issue auth code
            window.location.replace(goto);
            return;
          }
        ...
      }
    ...
    }

    For security reasons your custom UI must validate that the URL in the goto parameter matches a domain you trust before redirecting to it.

    Failure to validate the domain of the goto URL before redirecting could result in link hijacking or other security-related problems.

  6. Due to the presence of the goto parameter, the custom UI app can now redirect to the OAuth 2.0 /authorize endpoint, using the session token to authenticate the request.

    To authenticate the user the browser attaches the session token as a cookie in the request to the /authorize endpoint.

    Your server issues session token cookies for use on the same domain you have assigned to it. That domain will be one of the following:

    • The original URL for the server, for example:

      • openam-forgerock-sdks.forgeblocks.com (PingOne Advanced Identity Cloud tenants)

      • openam.example.com (PingAM servers)

    • A custom domain assigned to the server, for example:

      • id.mycompany.com

    If the custom UI app is running on a different domain than your server then browsers consider the cookie to be from a third party.

    Some browsers, such as Safari block access to third-party cookies, so the requests that use them appear to not be authenticated.

    For this tutorial you can disable third-party cookie checks in the browser, but for production you must ensure your custom UI and your server are sharing the same domain.

  7. The OAuth 2.0 client accepts the request, and returns the authorization code to the client application.

    The URL of the client app must match one of the redirect URIs listed in the OAuth 2.0 client configuration.

  8. The client application recognizes that an authorization code is present and that authentication was a success, and can now exchange the authorization code by calling the /access_token OAuth 2.0 endpoint.

  9. The server validates the authorization code and issues the access token, an ID token, and if enabled, refresh tokens.

    The client app can now call the userinfo endpoint, using the access token as a bearer token for authentication, and retrieve information about the user.

Tutorial steps

Complete the following tasks to try out this tutorial:

Before you begin

Before you begin this tutorial ensure you have downloaded the sample code from our sample code repository.

You will also need to determine the local IP address of your computer, and create a DNS alias from which to run the client sample app.

Part 1. Configuring your PingAM server or PingOne Advanced Identity Cloud tenant

In this section you configure your PingAM server or PingOne Advanced Identity Cloud tenant with an OAuth 2.0 client to accept connections from the sample client apps.

The OAuth 2.0 client also contains the configuration to redirect your users to authenticate using the custom UI sample app running on your local IP address.

Lastly, you configure Cross-origin Resource Sharing (CORS) to allow the sample UI app, and the client JavaScript app to connect to protected endpoints.

Part 2. Running the JavaScript custom UI sample app

In this section you configure the embedded login sample JavaScript app to act as your custom UI.

Part 3. Running a client sample app

The final step is to configure and run client OIDC sample apps.

These sample apps start the OAuth 2.0 flow on your PingAM server or PingOne Advanced Identity Cloud tenant, which redirects the user to your custom UI sample app, running locally on your computer.

After authentication the server redirects users back to the client sample apps and appends the code parameter, which your client app uses to complete the OAuth 2.0 flow.