mauriciovigolo / keycloak-angular

Easy Keycloak setup for Angular applications.
MIT License
725 stars 278 forks source link

Standalone bootstrap: withEnabledBlockingInitialNavigation() causes isLoggedIn() to return false in AuthGuard #559

Open Faedryth opened 5 months ago

Faedryth commented 5 months ago

Bug Report or Feature Request (mark with an x)

- [x] bug report -> please search for issues before submitting
- [ ] feature request

Versions.

angular 16.2.0 keycloak-js 23.0.7 keycloak-angular 14.2.0

Repro steps.

I am initializing my KeycloakService with 'login-required' when boostrapping my standalone Angular application:

function initializeKeycloak(keycloak: KeycloakService) {
    return () =>
        keycloak.init({
            config: {
                url: 'myUrl',
                realm: 'myRealm',
                clientId: 'myClientId'
            },
            loadUserProfileAtStartUp: true,
            initOptions: {
                onLoad: 'login-required',
                redirectUri: 'http://localhost:4200/intra'
            }
        });
}

bootstrapApplication(AppComponent, {
    providers: [        
        importProvidersFrom(KeycloakAngularModule),
        {
            provide: APP_INITIALIZER,
            useFactory: initializeKeycloak,
            multi: true,
            deps: [KeycloakService]
        },

Once the login is successful, the application is redirected to the '/intra' path, which is protected by an AuthGuard:

export const canActivate: CanActivateFn = async (route: ActivatedRouteSnapshot) => {
    const keycloakService = inject(KeycloakService);

    const isAuthenticated = await keycloakService.isLoggedIn();
    if (isAuthenticated) {
        return isAccessAllowed(route);
    } else {
        return router.parseUrl('/home');
    }
};

But keycloakService.isLoggedIn(); was always returning False even though we were coming here after the redirection after logging-in! I debugged it to make sure things were happening in the correct order and they were:

  1. bootstrap with login required
  2. login with keycloak
  3. redirect to /intra
  4. CanActivate says isLoggedIn() = False

After some digging I found topics talking about issues caused by the initialNavigation option. I then realized I was providing my router with the withEnabledBlockingInitialNavigation option: provideRouter(appRoutes, withEnabledBlockingInitialNavigation()), This option had been automatically added by Angular when I used the nx @angular/core:standalone command to turn my module-based application into a standalone application. Removing this option fixed the issue. I am now seeing isLoggedIn() = True in my AuthGuard.

Desired functionality.

I'm not sure if this is a bug or if this behaviour is expected. I already fixed my issue, I'm creating this post to help others who would have the same issue when migrating to Standalone applications.

syedhannan commented 4 months ago

I dont have withEnabledBlockingInitialNavigation() in the provideRouter() but still I get the isLoggedIn as false. I have a similar setup of "login-required" in keycloak and then checking the auth guard for isLoggedIn(). Any idea what the exact issue is?

Ashkan4472 commented 3 months ago

any update on this? I found that if your routes depend on keycloak guards and you use withEnabledBlockingInitialNavigation, because withEnabledBlockingInitialNavigation makes routes initial first before initialing the root component, causes keycloak to initiate after being used and makes a race condition