davide angelillo
davide angelillo

Reputation: 61

Keycloak does not login with checkLoginIframe true, refresh token is undefined

I'm trying to set up a Keycloak client using Angular 10 (the Keycloak server version is 7.0.1) but I'm experiencing some issues with the checkLoginIframe option.

I have a check-sso Keycloak situation, where the client does not need to be authenticated the whole time, but, every time I try to perform a login, I get an error after the redirect to my application. The error is: [KEYCLOAK] Failed to refresh token.

In the network tab I can see the client sends a request to the Keycloak server to refresh the token but the body for the call has undefined refresh token, so the response is 400.

I also noticed that the result of the "init" Keycloak function is true, but still the Keycloak instance has "authenticated" field set to false.

I tried to set the checkLoginIframe to false and it works, but the application performs many redirects before being instanciated and the route on which the application was gets lost (so the user gets redirected to the home page)

initializeKeycloak(): Observable<any> {
    const keycloak = new Keycloak('/assets/keycloak.json');
    // const keycloak = new Keycloak('/assets/keycloak.json');
    let initOptions = {
      onLoad: 'check-sso',
      silentCheckSsoRedirectUri: window.location.origin + AppConstants.SILENT_CHECK_SSO_ROUTE,
      promiseType: 'native',
      redirect_uri: window.location.href,
      checkLoginIframe: true,
      // enableBearerInterceptor: true,
      // bearerExcludedUrls: ['/assets'],
      flow: 'standard',
      silentCheckSsoFallback: false
    };

    return from(keycloak.init(initOptions)).pipe(
      tap(authenticated => {
        console.log(authenticated)
        this._keycloak = keycloak;
        console.log(this._keycloak)
      }),
      mergeMap(/*my application logic for the logged user data fetch*/),
      catchError((err) => {
        console.error(err);
        throw err;
      })
    );
  }

Upvotes: 6

Views: 9688

Answers (1)

davide angelillo
davide angelillo

Reputation: 61

I found a workaround (which maybe is just the correct way to do it) implementing a semaphore. The issue was related to Keycloak instance being initialized after the application startup (because it is asyncronous) while the application logic wanted to refresh the token almost instantly.

I just added an header interceptor which catches every call and waits for Keycloak to be initialized before releasing the calls.

Anyway i had to set checkLoginIframe to false, but the redirect is not happening anymore.

  private async waitForInit() {
    for (let i = 0; i < 5; i++) {
      if (this.ssoService.isInitialized()) {
        break;
      }
      await this.sleep(500);
    }
  }

  private sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

Upvotes: 0

Related Questions