How to force re-login for users

There aren’t detailed docs of the cookies (there should be). I’m going to write down a sketch here, if anyone would like to make a PR adding a formal description to the docs.

Cookies used by jupyterhub:

  • jupyterhub-hub-login
    • This is the login token when visiting hub-served pages (main login, spawn, etc.)
    • encrypted (resetting cookie secret effectively revokes this cookie)
    • restricted to path: /hub/ so that only the Hub process receives it.
    • If this cookie is set, the user is logged in.
  • jupyterhub-user-username
    • This is the cookie used for authenticating with a single-user server
    • encrypted (resetting cookie secret effectively revokes this cookie)
    • set by the single-user server after OAuth with the Hub
    • set on /users/name so that only the user’s server receives it
    • effectively the same as jupyterhub-hub-login, but for the single-user server instead of the Hub
    • contains an OAuth access token, which is checked with the Hub to authenticate the browser. Each OAuth access token has a session id (see below)
    • To avoid hitting the Hub on every request, the authentication response is cached. To avoid a stale cache, the cache key is both the token and session id.
  • jupyterhub-session-id
    • set on / so all endpoints receive it, can clear it, etc.
    • this is a random string, meaningless in itself, and the only cookie shared by the Hub and single-user servers
    • its sole purpose is to to coordinate logout of the multiple oauth cookies.
  • jupyterhub-user-name-oauth-state
    • a short-lived cookie, used solely to store and validate oauth state. Only set while oauth between the notebook and the Hub is processing

Logging in

The login process, starting with no cookies and accessing an running server at /user/name (the most complicated case)

  • user visits /user/name (served by notebook)
  • jupyterhub-user-name is not set, login process begins. That’s OAuth with the Hub, redirect to /hub/api/oauth2/authorize
  • /hub/api/oauth2/authorize (served by hub) is an authenticated page. jupyterhub-hub-login is not set, redirect to /hub/login to begin login process
  • login process may be a form or external oauth, etc.
  • on successful login, jupyterhub-hub-login and jupyterhub-session-id are set, redirect back to /hub/api/oauth2/authorize
  • authenticated access to /hub/api/oauth2/authorize completes OAuth process with an oauth code and redirects back to /users/name/oauth_callback (will start here if already authenticated with the Hub at the time of requesting access to /user/name)
  • /users/name/oauth_callback (served by notebook) completes oauth with the Hub, retrieving an OAuth access token and storing it in jupyterhub-user-name
  • redirects back to /user/name, checks jupyterhub-user-name cookie
    • finds token
    • verifies token with the Hub via /hub/api/authorizations/token
    • caches response using jupyterhub-session-id and token together as key
    • allows access based on who is authenticated

Logging out

Clicking a logout button anywhere should:

  • redirect to /hub/logout (served by Hub)
  • which calls clear_login_cookie, which clears jupyterhub-hub-login
  • revokes all OAuth access tokens associated with jupyterhub-session-id
  • clears jupyterhub-session-id

After this, visiting /user/name will have jupyterhub-user-name set. This cookie is not cleared by the Hub. However, since jupyterhub-session-id is cleared, the cached authentication response will not be used. The Hub will be consulted again for the validity of the token in jupyterhub-user-name, which was revoked during logout due to the session id, so authentication will fail and the cookie will be cleared and login will be prompted to start again.

11 Likes