OAuthenticator

repository·main·Indexed 19 days ago

https://github.com/jupyterhub/oauthenticator

A collection of JupyterHub authenticators that enable user login via OAuth2 identity providers. It includes specialized classes for providers such as GitHub, Google, Azure AD, GitLab, Auth0, Bitbucket, CILogon, Globus, MediaWiki, and OpenShift, as well as a GenericAuthenticator for custom OAuth 2.0 compliant services. Features include persisted authentication state for API access, custom 403 error handling, and mechanisms for refreshing OAuth access tokens.

Tokens
29.3K
Snippets
98
Records
152
Agent score
66%

What's inside oauthenticator

  1. Overview of OAuthenticator

    main
    OAuthenticator is a collection of JupyterHub plugins designed to facilitate authentication via common OAuth providers. It provides pre-built authenticators for popular services and serves as a foundation for developers to build custom authenticators for any OAuth 2.0 provider using the OAuthenticator base class.
  2. Supported OAuth2 Identity Providers in OAuthenticator

    main

    OAuthenticator provides specialized authenticator classes for several common OAuth2 identity providers. You can use these specific classes to plug OAuth2 authentication into JupyterHub. Supported providers include:

    • Auth0 (oauthenticator.auth0.Auth0)
    • Azure AD (oauthenticator.azuread.AzureAD)
    • Bitbucket (oauthenticator.bitbucket.Bitbucket)
    • CILogon (oauthenticator.cilogon.CILogon)
    • FeiShu (via jupyterhub_feishu_authenticator)
    • GitHub (oauthenticator.github.GitHub)
    • GitLab (oauthenticator.gitlab.GitLab)
    • Globus (oauthenticator.globus.Globus)
    • Google (oauthenticator.google.Google)
    • MediaWiki (oauthenticator.mediawiki.MediaWiki)
    • OpenShift (oauthenticator.openshift.OpenShift)

    If your provider is not listed, or if you need custom logic, you can use the GenericAuthenticator (oauthenticator.generic.GenericAuthenticator) which can be configured for any OAuth 2.0 identity provider or subclassed for further customization.

  3. How authorization works in OAuthenticator

    main

    OAuthenticator distinguishes between authentication (verifying who a user is via an external provider) and authorization (deciding if that user is allowed to use your JupyterHub).

    Authorization is managed through configuration options starting with allow or block.

    Key Rules:

    • Default Behavior: Since version 16, OAuthenticator blocks all users by default. You must explicitly grant access using at least one allow configuration.
    • Additive Nature of Allow Rules: Multiple allow rules are additive. If a user meets any allow rule, they are granted access. An allow rule cannot be used to exclude someone who was granted access by a different allow rule.
    • Priority of Block Rules: block configurations always take precedence. If a user is matched by both an allow rule and a block rule, they are denied access.
  4. Access expanded GitHub user information via auth_state

    main

    If you request expanded scopes, the additional user data is stored in the authenticator's auth_state structure.

    Requirements:

    1. Enable auth_state in your configuration.
    2. Install the Python cryptography package.

    Available Fields in auth_state:

    • id: Integer representing the GitHub account ID.
    • login: The GitHub username.
    • name: The user's full name.
    • email: The user's publicly visible email address.
    • access_token: The token used to authenticate to GitHub.
    • teams: A list of teams the user belongs to. Note: This requires the read:org scope AND setting populate_teams_in_auth_state = True on your GitHubOAuthenticator instance.

    How to use this data: To use these fields for provisioning (e.g., setting up home directories or git configs), you must subclass your current Spawner and modify it to read these fields from auth_state during the user provisioning lifecycle.

  5. Write a custom OAuthenticator subclass for advanced customization

    main

    If you require advanced features or need to customize the login and logout actions beyond standard OAuth flows, you should create a custom subclass of an OAuthenticator.

    When writing a custom class, you are responsible for defining the specific URLs and request logic required to interact with your identity provider. This allows for more granular control over how user information is fetched and how the authentication lifecycle is managed within JupyterHub.

  6. Using GenericOAuthenticator or custom Authenticators

    main
    Note that the OAuthenticator package is no longer adding support for new specific OAuth providers. To integrate a new OAuth provider, you should either use the GenericOAuthenticator or implement a custom authenticator by inheriting from the OAuthenticator base class.
  7. Use GenericAuthenticator for custom OAuth2 providers

    main
    If a specific authenticator for your identity provider does not exist, use GenericAuthenticator. This class can be configured to work with any OAuth 2.0 compliant service or extended by creating a new subclass to implement custom authentication logic.
  8. How user authentication refreshing works in OAuthenticator

    main

    OAuthenticator uses the JupyterHub refresh_user mechanism to periodically update user information (like group membership) and refresh OAuth access tokens.

    Lifecycle:

    • Every authenticated action (API request, page visit, server launch) triggers a check.
    • If the time since the last refresh exceeds Authenticator.auth_refresh_age (default: 5 minutes), JupyterHub triggers a refresh.
    • If the access token is expired but a refresh_token is available, a new access token is retrieved via the refresh token grant.
    • If the token cannot be refreshed (e.g., expired/revoked and no refresh token), the user is forced to log in again.

    Key Configuration:

    • Authenticator.auth_refresh_age: Controls the cache duration for auth info. Set to 0 to disable the time-based refresh trigger.
    • Authenticator.refresh_pre_spawn: When set to True, ensures auth info is refreshed immediately before a server is launched. This is highly recommended if the server needs a valid access token to access data sources or git repos.
    # Ensure auth is up-to-date before launching a server
    c.Authenticator.refresh_pre_spawn = True
    
    # Disable the automatic time-based refresh
    c.Authenticator.auth_refresh_age = 0
  9. Choose between GenericOAuthenticator and specialized provider authenticators

    main

    OAuthenticator offers two ways to implement OAuth2 authentication in JupyterHub:

    1. GenericOAuthenticator: A general-purpose class that works with any OAuth2 identity provider. Use this if you have a provider that does not have a dedicated class or if you prefer to manage all configuration manually.
    2. Specialized Authenticator Classes: These are pre-built classes for specific identity providers (e.g., GitHubOAuthenticator, GoogleOAuthenticator). Using a specialized class reduces the amount of manual configuration required and enables provider-specific features, such as restricting access to specific GitHub organizations.
  10. Set up Auth0 as an OAuthenticator provider

    main

    To use Auth0 for JupyterHub authentication, you must first register a 'Regular Web App' in your Auth0 dashboard. Once registered, you need to configure the Auth0OAuthenticator in your jupyterhub_config.py using your Auth0 application credentials and domain.

    c.JupyterHub.authenticator_class = "auth0"
    c.OAuthenticator.oauth_callback_url = "https://[your-domain]/hub/oauth_callback"
    c.OAuthenticator.client_id = "[your oauth2 application id]"
    c.OAuthenticator.client_secret = "[your oauth2 application secret]"
    c.Auth0OAuthenticator.auth0_domain = "[your-auth0-domain]"
  11. Set up GitHub authentication for JupyterHub

    main

    To use GitHub as an authentication provider, you must first register a GitHub OAuth application via GitHub's official documentation. Once registered, you can configure JupyterHub to use the GitHubOAuthenticator class.

    Ensure your GitHub OAuth application's callback URL is set to match the oauth_callback_url configured in JupyterHub (typically https://[your-domain]/hub/oauth_callback).

    c.JupyterHub.authenticator_class = "github"
    c.OAuthenticator.oauth_callback_url = "https://[your-domain]/hub/oauth_callback"
    c.OAuthenticator.client_id = "[your oauth2 application id]"
    c.OAuthenticator.client_secret = "[your oauth2 application secret]"