From f3625088b6330683c5a78ef06ca31c27ad8bdf79 Mon Sep 17 00:00:00 2001 From: Martin Claus Date: Thu, 4 Jan 2024 13:42:21 +0100 Subject: [PATCH 1/2] Switch to faster black-pre-commit-mirror Ref: https://github.com/psf/black/blob/23.12.1/.pre-commit-hooks.yaml --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db6e122..847c1e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - --py38-plus # Autoformat: Python code - - repo: https://github.com/psf/black + - repo: https://github.com/psf/black-pre-commit-mirror rev: 23.12.1 hooks: - id: black From 1f517ab29496551bbed87980cca2d4e072ed0c10 Mon Sep 17 00:00:00 2001 From: Martin Claus Date: Thu, 4 Jan 2024 13:43:04 +0100 Subject: [PATCH 2/2] Make client_id's type a list or set --- docs/source/lti13/getting-started.md | 21 +++++++-------------- docs/source/lti13/reference.md | 2 +- examples/jupyterhub_config_lti13.py | 6 +++++- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/docs/source/lti13/getting-started.md b/docs/source/lti13/getting-started.md index a061514..1449a35 100644 --- a/docs/source/lti13/getting-started.md +++ b/docs/source/lti13/getting-started.md @@ -7,7 +7,8 @@ Start by navigating to your [LMS vendor's integration section](lms-integration.m During the tool registration process, you should obtain the following information which is necessary to complete the setup of the LTI Authenticator plugin: - `issuer`: URL of the LMS platform used for identification -- `client_id`: opaque ID of the tool registration at the platform +- `client_id`: opaque ID of the tool registration at the platform. + You may obtain multiple client IDs, e.g. if you do multiple [single-tenant registrations](https://www.imsglobal.org/spec/lti/v1p3#single-tenant-tool-registered-and-deployed-once) within your LMS with the same JupyterHub instance. ```{note} If your LMS is not listed feel free to send us a PR with instructions for this new LMS. @@ -21,14 +22,13 @@ See the [configuration reference](reference) for a complete list of available co The required settings to get authentication via LTI 1.3 to work are: - `issuer`: the URL of your LMS platform. If your LMS is served from `https://canvas.instructure.com`, the issuer is `https://canvas.instructure.com`. -- `client_id`: opaque ID, typically generated by the LMS when a tool is registered there. - You can specify either a single client ID or a set of client IDs, e.g. if you do multiple [single-tenant registrations](https://www.imsglobal.org/spec/lti/v1p3#single-tenant-tool-registered-and-deployed-once) within your LMS with the same JupyterHub instance. +- `client_id`: set or list of opaque IDs, typically generated by the LMS when a tool is registered there. - `authorize_url`: Authorization endpoint of the LMS platform. The URL to which authorization requests are sent by the authenticator as part of the [OIDC implicit flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post). E.g. `https://canvas.instructure.com/api/lti/authorize_redirect`. - `jwks_endpoint`: An endpoint of the LMS from which JupyterHub can obtain the [JWKS](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets) to verify and decode any received [JWT](https://auth0.com/docs/secure/tokens/json-web-tokens). E.g. `https://canvas.instructure.com/api/lti/security/jwks`. -A valid minimal configuration in the `jupyterhub_config,py` may look like this +A valid minimal configuration in the `jupyterhub_config.py` may look like this ```python c.JupyterHub.authenticator_class = "ltiauthenticator.lti13.auth.LTI13Authenticator" @@ -43,7 +43,7 @@ c.LTI13Authenticator.authorize_url = "https://canvas.instructure.com/api/lti/aut c.LTI13Authenticator.jwks_endpoint = "https://canvas.instructure.com/api/lti/security/jwks" # The external tool's client id as represented within the platform (LMS) -c.LTI13Authenticator.client_id = "125900000000000329" +c.LTI13Authenticator.client_id = ["125900000000000329"] ``` ## Username Key Setting @@ -104,19 +104,12 @@ hub: authorize_url: "https://canvas.instructure.com/api/lti/authorize_redirect" # The external tool's client id as represented within the platform (LMS) # Typically created by the platform when registering the tool. - client_id: "125900000000000329" + client_id: + - "125900000000000329" # The platform's JWKS endpoint url providing public key sets used to verify the ID token jwks_endpoint: "https://canvas.instructure.com/api/lti/security/jwks" ``` -If you like to set multiple client IDs, you need to use yamls list notation: - -```yaml -client_id: - - "125900000000000329" - - "125900000000000330" -``` - ## Deal with Synchronization Issues (iat, nbf, exp) The underlying OIDC Implicit flow protocol requires some checks involving token issuing time. diff --git a/docs/source/lti13/reference.md b/docs/source/lti13/reference.md index 34adab2..54e97c4 100644 --- a/docs/source/lti13/reference.md +++ b/docs/source/lti13/reference.md @@ -28,7 +28,7 @@ hub: | tool_description | No | Description of the tool within the config JSON | `"Launch interactive Jupyter Notebooks with JupyterHub"` | | username_key | No | The LTI 1.3 launch parameter that contains the JupyterHub username value | `"email"` | | issuer | Yes | The platform's issuer identifier. A case-sensitive URL provided by the platform | | -| client_id | Yes | The client ID or a list of client IDs identifying the JuyterHub within the LMS platform. Must contain the client IDs created when registering the tool on the LMS platform. Possible values are of type `str` or `set[str]`. | | +| client_id | Yes | List or set of client IDs identifying the JuyterHub within the LMS platform. Must contain the client IDs created when registering the tool on the LMS platform. Possible values are of type `list[str]` or `set[str]`. | | | authorize_url | Yes | Authorization end-point of the platform's identity provider. Provided by the platform. | | | jwks_endpoint | Yes | Platform's jwks endpoint. Provided by the platform | | | jwks_algorithms | No | List of supported signature methods | `["RS256"]` | diff --git a/examples/jupyterhub_config_lti13.py b/examples/jupyterhub_config_lti13.py index 63fa08d..e4380cf 100644 --- a/examples/jupyterhub_config_lti13.py +++ b/examples/jupyterhub_config_lti13.py @@ -33,7 +33,11 @@ os.getenv("LTI13_AUTHORIZE_URL") or "https://canvas.instructure.com/api/lti/authorize_redirect" ) -c.LTI13Authenticator.client_id = os.getenv("LTI13_OAUTH_CLIENT_ID") or {""} +# The client ids are comma separated +if client_id := os.getenv("LTI13_OAUTH_CLIENT_ID"): + c.LTI13Authenticator.client_id = client_id.split(",") +else: + c.LTI13Authenticator.client_id = {""} c.LTI13Authenticator.jwks_endpoint = ( os.getenv("LTI13_JWKS_ENDPOINT") or "https://canvas.instructure.com/api/lti/security/jwks"