Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid "timeout when waiting for 3rd party check iframe message" with Keycloak and Angular

I'm trying to securize an Angular app with a Keycloak server. I've followed some tutorials that give more or less the same instructions in order to do so, but I got stuck with the following error:

Timeout when waiting for 3rd party check iframe message.

I start my keycloak server using the following docker-compose configuration:

auth:
  container_name: nerthus-tech-auth
  image: quay.io/keycloak/keycloak:17.0.1
  command: start-dev
  environment:
    KEYCLOAK_ADMIN: admin
    KEYCLOAK_ADMIN_PASSWORD: admin
    KC_DB: postgres
    KC_DB_URL: jdbc:postgresql://database:5432/keycloak
    KC_DB_USERNAME: keycloak
    KC_DB_PASSWORD: str0ngP@ssword
  ports:
    - 10010:8080

I've created a realm (nerthus) and a client (blog) which is public and has the following configuration:

  • Root URL: http://localhost:4200
  • Valid redirect URLs: http://localhost:4200/* (which in my understanding I should be able to abbreviate as *)
  • Web origins: +

On the Angular app side, I've installed the keycloak-angular and keycloak-js dependencies:

"keycloak-angular": "^9.1.0",
"keycloak-js": "^16.1.1"

I've also registered an initializer for Keycloak:

providers: [
  {
    provide: APP_INITIALIZER,
    useFactory: initializeKeycloak,
    multi: true,
    deps: [KeycloakService]
  }
]
function initializeKeycloak(keycloakService: KeycloakService) {
  return () => keycloakService.init({
                                      config: {
                                        url: 'http://localhost:10010',
                                        realm: 'nerthus',
                                        clientId: 'blog'
                                      }
                                    });
}

For that one I also tried to use initOptions.onLoad (with "login-required" and "check-sso"), but that causes the app to require authentication to access any page, which is not the intended behaviour.

I want only the guarded page to require authentication. Hence the guard I set up:

@Injectable({
  providedIn: 'root'
})
export class AuthGuard extends KeycloakAuthGuard {
  constructor(protected override readonly router: Router,
              protected override readonly keycloakAngular: KeycloakService) {
    super(router, keycloakAngular);
  }

  async isAccessAllowed(route: ActivatedRouteSnapshot,
                        state: RouterStateSnapshot): Promise<boolean | UrlTree> {
    if (!this.authenticated) {
      await this.keycloakAngular.login({ redirectUri: window.location.origin + state.url });
    }

    return this.authenticated;
  }
}

Surely I'm missing something, but I can't make it work. I tried to be succinct, so if some important information is missing, please ask me.

like image 884
François Dupire Avatar asked Dec 23 '25 00:12

François Dupire


1 Answers

My solution is set the checkLoginIframe to false. Below is my configuration:

 keycloak.init({
  config: {
      url: 'http://localhost:10010',
      realm: 'nerthus',
      clientId: 'blog'
  },
  initOptions: {
    
    pkceMethod: 'S256', 
    // must match to the configured value in keycloak
    redirectUri: 'http://localhost:4200/your_url',   
    // this will solved the error 
    checkLoginIframe: false
  }});

Hopes it will helps. =)

like image 184
shuyu Avatar answered Dec 24 '25 19:12

shuyu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!