mauriciovigolo / keycloak-angular

Easy Keycloak setup for Angular applications.
MIT License
727 stars 279 forks source link

Login trying to refresh a dead token #316

Open corte opened 3 years ago

corte commented 3 years ago

Bug Report or Feature Request (mark with an x)

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

Versions.

Angular: 10.2 Keycloak-js: 12.0.1 Keycloak-angular: 8.1.0

Repro steps.

  1. After successfully logging in, set the browser to offline mode: image

  2. Wait for both token and refresh_token expire.

  3. Set browser to online again and refresh the page (I did it on a route protected by my auth-guard - implements KeycloakAuthGuard)

  4. this.authenticated will be false causing the library to redirect to keycloak login page.

  5. After logging in again the browser redirects to my page (protected route again)

  6. this.authenticated still false causing login again and a redirect loop.

The log given by the failure.

Nothing really in the logs, but when looking at the network tab there's a request to the token endpoint that is failing. When checking that request it looks like the library is trying to refresh the token that is already expired, causing Keycloak to return a 400 Bad Request: image

Desired functionality.

A completely new login, ignoring the state and not trying to refresh a dead token.

My attempts

I tried a couple of different things, like changing onLoad configuration from 'check-sso' to 'login_required'. Still same errror. I have an auth service class that I use to call the login method on Keycloak-angular. I tried also clearing the token before calling login, but that doesn't work either:

    public async startAuthentication(): Promise<void> {
        this.keycloak.clearToken();
        return await this.keycloak.login();
    }

I also tried creating an unprotected route called auth-callback and redirecting there, to avoid the auth-guard logic being triggered while logging in:

    public async startAuthentication(): Promise<void> {
        this.keycloak.clearToken();
        return await this.keycloak.login({
            redirectUri: `${window.location.protocol}//${window.location.host}/auth-callback`,
        });
    }

That stops the redirect loop, but when I try to access a protected route again, the login is triggered again, the request to the endpoint still fails and I'm back to auth-callback route every time.

My keycloak init config:

keycloak.init({
    config: {
      url: 'https://<keycloak_url>/auth',
      realm: '<my_realm>',
      clientId: '<my_app>-client'
    },
    initOptions: {
      checkLoginIframe: false,
      flow: 'standard',
      onLoad: 'check-sso',
      silentCheckSsoRedirectUri:
        `${window.location.protocol}//${window.location.host}/assets/silent-check-sso.html`
    },
    enableBearerInterceptor: false,
    loadUserProfileAtStartUp: false,
    bearerExcludedUrls: ['/assets', '/clients/public']
});

I'm not sure what to try next or if I have some mistake on my keycloak client's configuration. Any suggestions?

furkick commented 3 years ago

Hi, just wondering if you have found a solution to this issue? It sounds very similar to an issue I am currently having.

arnotixe commented 1 year ago

I got this kind of behavior when setting Accesstoken lifespan to 1 min, Client session idle to 2 min, Client session Max to 3min. (per client settings). Symptom is I can never sign in, even if I try signIn() on a button, it still seems to try and want to exchange the dead refresh_token instead of signing in, because I see the RefreshAccessTokenError even when doing signOut() and then signIn()

Keycloak 21.0.2

Works as expected when only messing with Accesstoken lifespan and leaving the Client session to "inherit"

Will keep digging and update if I find more.