Skip to content

User part of multiple groups in keycloak is denied access to Jupyterhub #761

Description

@mt-cpo

Bug description

I am installing jupyterhub using Helm and Keycloak for authentication. When a user is part of one group (ex: jupyter_users) and I declared in:

allowed_groups:
        - "/jupyter_users"

It works, but if I add that same user to another group (ex: he is part of jupyter_users and foo group in keycloak) then he get denied access to jupyterhub.

How to reproduce

  1. Helm install using the following config:
hub:
  config:
    JupyterHub:
        authenticator_class: generic-oauth
    GenericOAuthenticator:
        login_service: "Keycloak"
        client_id: "$JUPYTERHUB_CLIENT_ID"
        client_secret: "$client_secret"
        oauth_callback_url: "http://$JUPYTERHUB_DOMAIN/hub/oauth_callback"
        authorize_url: "http://$KEYCLOAK_DOMAIN/realms/$KEYCLOAK_REALM/protocol/openid-connect/auth"
        token_url: "http://$KEYCLOAK_DOMAIN/realms/$KEYCLOAK_REALM/protocol/openid-connect/token"
        userdata_url: "http://$KEYCLOAK_DOMAIN/realms/$KEYCLOAK_REALM/protocol/openid-connect/userinfo"
        scope:
        - openid
        - email
        - profile
        - groups
        username_claim: "preferred_username"
        allowed_groups:
        - "/jupyterhub_users"
        admin_groups:
        - "/jupyterhub_admins"
        claim_groups_key: "groups"

singleuser:
    defaultUrl: "/lab"

proxy:
  service:
    type: $SERVICE_TYPE
    nodePorts:
      http: 30696
      https: 30696
  https:
    enabled: true
  1. Create a group in Keycloak called jupyterhub_users
  2. Create a user and add him to group jupyterhub_users
  3. Login to Jupyterhub -> This should work
  4. Create a second group in Keycloak called foo
  5. Add the same user to the group foo
  6. Login to Jupyterhub -> This should throw 500 internal server error
Logs
hub-55f66fc556-g6522 [D 2024-09-17 10:58:43.282 JupyterHub reflector:374] pods watcher timeout
hub-55f66fc556-g6522 [D 2024-09-17 10:58:43.282 JupyterHub reflector:289] Connecting pods watcher
hub-55f66fc556-g6522 [D 2024-09-17 10:58:44.152 JupyterHub log:192] 200 GET /hub/health (@10.244.0.1) 1.29ms
hub-55f66fc556-g6522 [D 2024-09-17 10:58:46.151 JupyterHub log:192] 200 GET /hub/health (@10.244.0.1) 0.83ms
hub-55f66fc556-g6522 [E 2024-09-17 10:58:47.459 JupyterHub oauth2:683] Error Fetching user info... 401 GET http://keycloak.default/realms/omniops/protocol/openid-connect/userinfo: 
hub-55f66fc556-g6522 [E 2024-09-17 10:58:47.460 JupyterHub web:1875] Uncaught exception GET /hub/oauth_callback?state=eyJzdGF0ZV9pZCI6ICJmZTg1ZWUzODdhZmM0ZDNmOGQxMmVmNWQ4ZDAxMDNmMCJ9&session_state=647de1bc-b9dc-4da9-99a1-ba03190c01ba&iss=http%3A%2F%2Fkeycloak.default%2Frealms%2Fomniops&code=dd3f8514-8d4a-4b76-9b50-065c84135236.647de1bc-b9dc-4da9-99a1-ba03190c01ba.a481311f-ef17-4bb2-8452-8e0566214afb (::ffff:10.244.0.1)
hub-55f66fc556-g6522     HTTPServerRequest(protocol='http', host='jupty', method='GET', uri='/hub/oauth_callback?state=eyJzdGF0ZV9pZCI6ICJmZTg1ZWUzODdhZmM0ZDNmOGQxMmVmNWQ4ZDAxMDNmMCJ9&session_state=647de1bc-b9dc-4da9-99a1-ba03190c01ba&iss=http%3A%2F%2Fkeycloak.default%2Frealms%2Fomniops&code=dd3f8514-8d4a-4b76-9b50-065c84135236.647de1bc-b9dc-4da9-99a1-ba03190c01ba.a481311f-ef17-4bb2-8452-8e0566214afb', version='HTTP/1.1', remote_ip='::ffff:10.244.0.1')
hub-55f66fc556-g6522     Traceback (most recent call last):
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/tornado/web.py", line 1790, in _execute
hub-55f66fc556-g6522         result = await result
hub-55f66fc556-g6522                  ^^^^^^^^^^^^
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/oauthenticator/oauth2.py", line 210, in get
hub-55f66fc556-g6522         user = await self.login_user()
hub-55f66fc556-g6522                ^^^^^^^^^^^^^^^^^^^^^^^
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/jupyterhub/handlers/base.py", line 928, in login_user
hub-55f66fc556-g6522         authenticated = await self.authenticate(data)
hub-55f66fc556-g6522                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/jupyterhub/auth.py", line 493, in get_authenticated_user
hub-55f66fc556-g6522         authenticated = await maybe_future(self.authenticate(handler, data))
hub-55f66fc556-g6522                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/oauthenticator/oauth2.py", line 1063, in authenticate
hub-55f66fc556-g6522         user_info = await self.token_to_user(token_info)
hub-55f66fc556-g6522                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/oauthenticator/oauth2.py", line 978, in token_to_user
hub-55f66fc556-g6522         return await self.httpfetch(
hub-55f66fc556-g6522                ^^^^^^^^^^^^^^^^^^^^^
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/oauthenticator/oauth2.py", line 718, in httpfetch
hub-55f66fc556-g6522         return await self.fetch(
hub-55f66fc556-g6522                ^^^^^^^^^^^^^^^^^
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/oauthenticator/oauth2.py", line 684, in fetch
hub-55f66fc556-g6522         raise e
hub-55f66fc556-g6522       File "/usr/local/lib/python3.11/site-packages/oauthenticator/oauth2.py", line 663, in fetch
hub-55f66fc556-g6522         resp = await self.http_client.fetch(req, **kwargs)
hub-55f66fc556-g6522                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
hub-55f66fc556-g6522     tornado.httpclient.HTTPClientError: HTTP 401: Unauthorized
hub-55f66fc556-g6522     
hub-55f66fc556-g6522 [D 2024-09-17 10:58:47.461 JupyterHub base:1471] No template for 500
hub-55f66fc556-g6522 [E 2024-09-17 10:58:47.475 JupyterHub log:184] {
hub-55f66fc556-g6522       "X-Forwarded-Host": "jupty",
hub-55f66fc556-g6522       "X-Forwarded-Proto": "http",
hub-55f66fc556-g6522       "X-Forwarded-Port": "80",
hub-55f66fc556-g6522       "X-Forwarded-For": "::ffff:10.244.0.1",
hub-55f66fc556-g6522       "Cookie": "_xsrf=[secret]; oauthenticator-state=[secret]",
hub-55f66fc556-g6522       "Accept-Language": "en-US,en;q=0.9",
hub-55f66fc556-g6522       "Accept-Encoding": "gzip, deflate",
hub-55f66fc556-g6522       "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
hub-55f66fc556-g6522       "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
hub-55f66fc556-g6522       "Upgrade-Insecure-Requests": "1",
hub-55f66fc556-g6522       "Cache-Control": "max-age=0",
hub-55f66fc556-g6522       "Connection": "keep-alive",
hub-55f66fc556-g6522       "Host": "jupty"
hub-55f66fc556-g6522     }
hub-55f66fc556-g6522 [E 2024-09-17 10:58:47.475 JupyterHub log:192] 500 GET /hub/oauth_callback?state=[secret]&session_state=[secret]&iss=http%3A%2F%2Fkeycloak.default%2Frealms%2Fomniops&code=[secret] (@::ffff:10.244.0.1) 27.21ms

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions