Sign-in Widget: Redirect from IdP Federation returns user to dashboard, not app

Hello,

We are facing a similar issue to what was reported in this ticket by another user when using the Okta Self-Hosted Sign-in Widget: Okta Sign In Widget doesn't work with Google Idp

In our case, we are building Angular applications which will use the Self-Hosted Sign-in Widget to authenticate users. Specifically, we are looking to use the IdP Discovery feature on the widget as “Employee” accounts will federate over to our “workforce” Okta tenant from our “customer” Okta tenant (we are integrating these apps with the customer tenant).

We have based our initial implementations around the following Okta code sample: samples-js-angular/custom-login at master · okta/samples-js-angular · GitHub

When an “Employee” account logs into the app with the IdP Discovery flag turned on (set to ‘true’), the authentication of that user with the other tenant works as expected: they are redirected to the “workforce” tenant, authenticate there with their credentials/MFA, then are redirected back to the “customer” tenant. That said, the user is redirected back to the Okta “customer” tenant End-user dashboard instead of the app. Is there something which we are missing as part of our config?

The linked article from andrewliang makes me think this is possible and something is simply being missed within our Widget config/code. I’ve been working on this for some time so I essentially am looking to confirm 1. Is what we are attempting to do possible? and 2. If so, what guidance is there may be over what we are missing?

Any insight is greatly appreciated.

LOGIN COMPONENT.TS/WIDGET CONFIG:

import { Component, OnInit } from '@angular/core';
import { OktaAuth, Tokens } from '@okta/okta-auth-js'; // @ts-ignore
import * as OktaSignIn from '@okta/okta-signin-widget';
import sampleConfig from '../app.config';

const DEFAULT_ORIGINAL_URI = window.location.origin;

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})

export class LoginComponent implements OnInit {
  signIn: any;
  constructor(public oktaAuth: OktaAuth) {
    this.signIn = new OktaSignIn({
      baseUrl: sampleConfig.oidc.issuer.split('/oauth2')[0], //Set in app.config.ts
      clientId: sampleConfig.oidc.clientId, //Set in app.config.ts
      redirectUri: sampleConfig.oidc.redirectUri, //http://localhost:8080/login/callback
      logo: 'assets/angular.svg',
      i18n: {
        en: {
          'primaryauth.title': 'Sign in to Angular & Company',
        },
      },
      authClient: oktaAuth,
      authParams: {
        pkce: true
      },
      features: {
        idpDiscovery: true
      },
      idpDiscovery:{
        requestContext: sampleConfig.oidc.redirectUri
      }
    });
  }

ngOnInit() {
    // When navigating to a protected route, the route path will be saved as the `originalUri`
    // If no `originalUri` has been saved, then redirect back to the app root
    const originalUri = this.oktaAuth.getOriginalUri();
    if (!originalUri || originalUri === DEFAULT_ORIGINAL_URI) {
      this.oktaAuth.setOriginalUri('/');
    }
    
    this.signIn.showSignInToGetTokens({
      el: '#sign-in-widget',
      scopes: sampleConfig.oidc.scopes
    }).then((tokens: Tokens) => {
      // Remove the widget
      this.signIn.remove();

      // In this flow the redirect to Okta occurs in a hidden iframe
      this.oktaAuth.handleLoginRedirect(tokens);
    }).catch((err: any) => {
      // Typically due to misconfiguration
      throw err;
    });
  }

  ngOnDestroy() {
    this.signIn.remove();
  }

}

Adding some additional information over things I have already tried, but yielded the same results:

Added idpDiscovery.requestContext within the widget config. Set requestContext to both ‘window.location.href’ and a static URL of ‘http://localhost:8080/’. Suggestion shown within this article: Okta Help Center (Lightning)

Set requestContext to a target Embed URL path (I.E. https://{okta domain}/home/oidc_client/{okta application id}/{other id generated by Okta}). Suggestion shown within this article: Okta Help Center (Lightning)

Adding another reply with additional information. I do believe the below article is accurately describing what is going on here:

https://support.okta.com/help/s/article/Relay-state-lost-when-using-IDP-Discovery-in-Sign-In-widget?language=en_US

  • The “RelayState” is not being passed over to our “workforce” Okta tenant by our “customer” okta tenant during the IdP Federation process.
  • The user authenticates at the “workforce” tenant (IdP) and is redirected back to the “customer” tenant (SP): with no RelayState set, the “customer” tenant doesn’t know where to send the user.
  • Since Okta doesn’t know where to send the user, it defaults to the base URL for the “customer” tenant. Seeing as the user is already authenticated, that base URL directs them to the user-dashboard.

I can see no RelayState being set when looking through the networking tab on Google Chrome while I test. Furthermore, if I were to manually (through my web-browser) add the RelayState parameter onto the “workforce” saml endpoint which our “customer” tenant is directing to, it will resolve (after authentication) to the URL set in the parameter:

https://{workforce tenant domain}/app/okta_org2org/{app id}/sso/saml?RelayState=http://localhost:8080/

That said… from the suggested resolution in the article, now I’m confused as to how the requestContext URL set in the widget config bridges this gap…