We developed an Experience Builder Dev Edition 1.17 experience that we deploy to our own web server, e.g., https://example.com/exb with our Enterprise 11.3 portal at https://example.com/portal.
We require that the user sign in to the application immediately, before any widgets are rendered and before they attempt to send HTTP/REST requests to any out of the box or custom services and rest apis. I.e., the out of the box "sign in when first accessing a protected resource" happens much too late in the worfklow for our custom services.
To that end we've implemented an app extension using APP_CONFIG_PROCESSOR that is called very early in the app startup. The extension calls SessionManager.signIn to initiate an OAuth flow against Enterprise Portal. (See the code at bottom for implementation details).
However, we've run into a couple issues.
P1. Running locally: The extension is not executed on a soft refresh.
When running everything locally via Experience Builder dev edition (i.e., npm run start) I've recently found that that extension code is not run on a soft refresh of the application (i.e., F5) however it is run on a hard refresh (CTRL-F5). If the extension code is not run I'm unable to set the token for some our our services and our widgets fail.
Q1. Shouldn't the extension point run regardless soft or hard page refreshes?
P2. Running the deployed app: Second out of the box sign prompt persists
When running the deployed application, after the user logs in via our initiated flow the application reloads and the user is prompted with a second out of the box sign in dialog. If they choose to sign in, they do so via a popup, and most things work. If they choose to cancel the sign in, the map and other widgets fail due to an invalid session/token/something else.
Q2. How do we initiate a sign in flow that fully signs in the user such that no subsequent sign prompts are required? Is SessionManager.signIn() insufficient?
Here is the code.
// extensions/login.ts
export default class Login implements extensionSpec.AppConfigProcessorExtension
{
  id = "my-awesome-login";
  widgetId: string;
  async process(appConfig: AppConfig): Promise<AppConfig> {
    try {
      await signIn("<myportal>", "myclientid");
      return Promise.resolve(appConfig);
    } catch (err) {
      console.error(err);
      return Promise.resolve(appConfig);
    }
  }
}
export async function signIn(portalUrl: string, clientId) {
  const sm = SessionManager.getInstance();
  const mainSession = sm?.getMainSession();
  const user = await mainSession?.getUser();
  const loggedIn = !!mainSession && !!user;
  if (!loggedIn) {
    const userSession = await sm.signIn({
      popup: false,
      desUrl: portalUrl,
      clientId: clientId,
      fromUrl: window.location.href,
      forceLogin: true,
    });
    // when popup is false the following code is unreachable
    // as the window refreshes to sign the user but is left
    // in place in case we want to turn popup: true
    // Set private _token variable in Usage Tracking Module
    setUsageToken(userSession.token);
  } else {
    // Set private _token variable in Usage Tracking Module
    setUsageToken((userSession.token);
  }
}cc @JunshanLiu ?
@Jianxia @Wei_Ying Using the Security options count as canceling the login popup and trigger the affects documented by @RyanTaylor.
Thanks for the post. I am using Experience Builder 1.17 and this does not seem to be available to me. I updated my post to reflect the version number.