solo-io / gloo

The Feature-rich, Kubernetes-native, Next-Generation API Gateway Built on Envoy

Home Page:https://docs.solo.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

oidcAuthorizationCode AuthConfig redirects to afterLogoutUrl instead of issuerUrl when access-token and refresh-token in Redis cache have expired

DuncanDoyle opened this issue · comments

Gloo Edge Product

Enterprise

Gloo Edge Version

1.16.9

Kubernetes Version

1.27.8

Describe the bug

Given an application that is protected with an oidcAuthorizationCode AuthConfig, in the following scenario the browser is redirected to the afterLogoutUrl instead of the issuerUrl:

  1. Access the application. Gloo sends a redirect to the IdP (Keycloak in my case).
  2. Login to Keycloak. The OAuth/OIDC "dance" is initiated (access-code exchange for access-token and refresh-token)
  3. A new session is created in Redis with the access-token and refresh-token.
  4. User is granted access to the application and redis session cookie is returned.
  5. Remove the session from Keycloak, simulating a session timeout, which basically means that the refresh-token can no longer be used to retrieve a new access-token.
  6. Wait till the access-token expires.
  7. Hit the application again, and observe that the user is redirected to the afterLogoutUrl instead of the IdP (Keycloak) login screen.

Note that in the case that you don't use afterLogoutUrl, the browser is redirected to the appUrl, and in my case, that URL is also protected with oidcAuthorizationCode flow ... so there is an immediate redirect to the IdP login screen.

Note that there is difference in behaviour between the case where Redis still has the session with the expired tokens, and the case where there is no Redis session at all anymore. When the session is still in Redis, we see the behaviour as described above. When the session is no longer in Redis, for example because we've set the maxAge of the session cookie (which sets a TTL on the session entry in Redis) ... the user is redirected to the issuerUrl and NOT to the afterLogoutUrl.

IMO, in the situation described here, where the user does NOT take the explicit action to logout (i.e. call the logoutPath), the user should be redirected to the issuerUrl and not the afterLogoutUrl.

Expected Behavior

The user/browser should be redirected to issuerUrl instead of afterLogoutUrl or appUrl if the tokens in the existing session in Redis have expired. The reasoning is that the user has not initiated an explicit logout action (i.e. calling logoutPath endpoint) and should therefore not be redirected to the afterLogoutUrl or appUrl.

Steps to reproduce the bug

Reproducer project here: https://github.com/DuncanDoyle/ge-9574-oidc-afterlogouturl

Additional Environment Detail

No response

Additional Context

No response

Related Issues

This behaviour seems to have been introduced as a fix to this issue: #4927

Example AuthConfig:

apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
  name: oauth-acf-auth
  namespace: gloo-system
spec:
  configs:
    - name: keycloak_oidc
      oauth2:
        oidcAuthorizationCode:
          afterLogoutUrl: http://www.google.com
          appUrl: http://api.example.com
          autoMapFromMetadata:
            namespace: solo_authconfig_oidc
          callbackPath: /callback
          clientId: webapp-client
          clientSecretRef:
            name: oauth
            namespace: gloo-system
          headers:
            accessTokenHeader: access_token
            idTokenHeader: id_token
            useBearerSchemaForAuthorization: true
          issuerUrl: http://keycloak.example.com/realms/master/
          logoutPath: /logout
          scopes:
            - email
          session:
            # Store the id_token and access_token in Redis, and only sent session ID back to the client.
            failOnFetchFailure: true
            redis:
              allowRefreshing: true
              cookieName: oidc-session
              headerName: oidc-session
              options:
                host: redis.gloo-system.svc.cluster.local:6379
              preExpiryBuffer: 2s