OIDC client + Identity Server 4, setting max_age silent token reniew not working

I have an angular 10 application with OIDC JS client as open id connect. On browser or tab close I need to redirect the user back to the login page.

By setting max_age to the UserManager the functionality is working fine, however, silent token reniew is not working while using the application and it redirects to the login page. The token got expire.

const settings: any = await response.json();
settings.automaticSilentRenew = true;
settings.includeIdTokenInSilentRenew = true;
settings.accessTokenExpiringNotificationTime = 30; // default 60
settings.checkSessionInterval = 5000; // default 2000;
settings.silentRequestTimeout = 20000;// default: 10000
settings.monitorSession = true;
settings.loadUserInfo = true;
settings.filterProtocolClaims = true;
settings.max_age = 10;
settings.prompt="login"
this.userManager = new UserManager(settings);


public async completeSignIn(url: string): Promise<IAuthenticationResult> {
    try {
      
      await this.ensureUserManagerInitialized();

      const user = await this.userManager.signinCallback(url);
      
      this.userSubject.next(user);
      return this.success(user && user.state);
    } catch (error) {
      console.log('There was an error signing in: ', error);
      return this.error('There was an error signing in.');
    }
  }

While doing some search I found that prompt="login" should work, but not able to solve it. How can I achieve if the application is active the silent token reniew should work if they close the browser or tab prompt the login screen.

Answer

max_age=10 is saying “if the user interactively signed in more than 10 seconds ago then force interactive authentication”. In short I don’t think you want that as it effectively disables silent renewal and will cause the authorize endpoint to return error=login_required if prompt=none is specified (which it will be for silent renewal).

Using sessionStorage to store UserManager state should acheive what you want as this is tied to the browser window and will be automatically cleared up if the window/tab is closed or the browser closed.

This will not affect the user’s session cookie on the IDP however so you’d still want to manually specify max_age=n or prompt=login when you are doing the interactive sign in (i.e. if no local client-side session currently exists). To do this you can pass additional params to signinRedirect rather than defining them at UserManager settings level:

await manager.signinRedirect({ prompt: "login" });

Additionally, since these params can be tampered with it’s wise to also check the auth_time claim in your backend to ensure the user really did authenticate recently.