Automatic login using angular-oauth2-oidc without presenting the login page

1.6k Views Asked by At

I want to automatically login the user with angular-oauth2-oidc, if there is an active session on the id server. But if thats not the case, i don't want to present the login page but just have in internal state set.

I tried with

service.loadDiscoveryDocumentAndTryLogin()

but that returns allways true without giving me any tokens or claims to get the user profile.

this is my config:

const defaultAuthConfig: AuthConfig = {
  // Url of the Identity Provider
  issuer: 'https://....net',
  tokenEndpoint: 'https://....net/oauth2/token',

   
  // URL of the SPA to redirect the user to after login
  redirectUri: window.location.origin + '/redirect',
  silentRefreshRedirectUri: window.location.origin + '/redirect',

   useSilentRefresh: true,

   clientId: 'server.code',

   responseType: 'code',

   scope: 'openid profile email offline_access api',

   showDebugInformation: true
};
1

There are 1 best solutions below

0
On

The tryLogin part just checks if you were just now redirected from the IDP to the Angular App, and if the URL contains login tokens and whatnot.

You are looking for a "silent" login right after that, before you decide you really need to ask the user to explicitly log in with a redirect flow. There are two ways to do that:

  1. With refresh_tokens if the risk (attack vectors) of offline_access and refresh tokens are worth it to you;
  2. With a "silent iframe refresh" if you can work around the modern browser limitiations around 3rd party cookies, e.g. by hosting your IDP on a subdomain of the domain that hosts your Angular app;

Regardless of which you configure, you make the library do said silent refresh by calling this.oauthService.silentRefresh() at the right time.

You can check the relevant code in my sample repository (which you can clone and run to see it in action), for reference here's the relevant code:

this.oauthService.loadDiscoveryDocument()
  .then(() => this.oauthService.tryLogin())
  .then(() => {
    if (this.oauthService.hasValidAccessToken()) {
      return Promise.resolve(); // already signed in
    }
    return this.oauthService.silentRefresh()
      .then(() => Promise.resolve())
      .catch(result => {
        // Consider sending the user to the login page here.
        return Promise.reject(result);
      });
  });