Skip to main content

JupyterHub authenticator implementing LTI v1

Project description

LTI Launch JupyterHub Authenticator

Documentation build status GitHub Workflow Status Latest PyPI version

Implements LTI v1 authenticator for use with JupyterHub.

This converts JupyterHub into a LTI Tool Provider, which can be then easily used with various Tool Consumers, such as Canvas, EdX, Moodle, Blackboard, etc.

So far, ltiauthenticator has been tested with EdX and Canvas. Documentation contributions are highly welcome!

Note that with this authenticator, going directly to the hub url will no longer allow you to log in. You must visit the hub through an appropriate Tool Consumer (such as EdX) to be able to log in.

Installation

You can install the authenticator from PyPI:

pip install jupyterhub-ltiauthenticator

Using LTIAuthenticator

EdX

  1. You need access to EdX Studio to set up LTI. You might have to contact your EdX Liaison to get access.

  2. Enable LTI Components for your course.

  3. Create a client key and client secret for use by edX to authenticate your hub. Open up any command line:

    1. Run openssl rand -hex 32 and save the output. This will be your LTI Client Key.
    2. Run openssl rand -hex 32 and save the output. This will be your LTI Client Secret.

    Now we will use these strings to allow edX and JupyterHub to authenticate each other.

    Note: These commands will simply generate strings for you, it will not store them anywhere on the computer. Therefore you do not need to run these commands on your JupyterHub server--we will be supplying them manually in the next few steps.

    Note: Anyone with these two strings will be able to access your hub, so keep them secure!!

  4. By default, the user's name will be the custom_canvas_user_id passed in by canvas. If you would like to use some other bit of information from the LTI request, you can pick what should be used as the user id.

    # Set the user's email as their user id
    c.LTIAuthenticator.username_key = 'lis_person_contact_email_primary'
    

    A partial list of keys in an LTI request is available to help. Your LMS provider might also implement custom keys you can use.

  5. Pick a name for edX to call your JupyterHub server. Then, along with the two random strings you generated in step 4, paste them together to create an LTI Passport String in the following format:

    your-hub-name:client-key:client-secret
    

    your-hub-name can be anything, but you'll be using it throughout edX to refer to your hub, so make it something meaningful and unique.

    Here's an example:

    stat100-jupyterhub:fca69fa2deda7d45dfdfa85f288d59b4b5f3d22bfca2ba891187fe5c551705a5:8ce3caca82f467f0896b92d548dfbddaca86edfcaaba8c9d6777dfae4d2e1db9
    

    Then add the Passport String to EdX. Remember to save your changes when done!

  6. Configure JupyterHub to accept LTI Launch requests from EdX. You do this by supplying JupyterHub with the client key & secret generated in step 3 (you don't need the hub name from step 4).

    Note: While you could paste these keys directly into your configuration file, they are secure credentials and should not be committed to any version control repositories. It is therefore best practice to store them securely. Here, we have stored them in environment variables.

    c.JupyterHub.authenticator_class = 'ltiauthenticator.LTIAuthenticator'
    c.LTIAuthenticator.consumers = {
        os.environ['LTI_CLIENT_KEY']: os.environ['LTI_CLIENT_SECRET']
    }
    

    A Hub can be configured to accept Launch requests from multiple Tool Consumers. You can do so by just adding all the client keys & secrets to the c.LTIAuthenticator.consumers traitlet like above.

  7. In a Unit where you want there to be a link to the hub, add an LTI Component.

    You should enter the following information into the appropriate component settings:

    LTI ID: The value you entered for your-hub-name in step 4.

    LTI URL: Should be set to your-hub-url/hub/lti/launch. So if your hub is accessible at http://datahub.berkeley.edu, LTI URL should be http://datahub.berkeley.edu/hub/lti/launch

    LTI Launch Target: Should be set to New Window.

    Custom parameters: The only currently supported custom parameter is next, which can contain the relative URL that the user should be redirected to after authentication. For example, if you are using nbgitpuller and want the user to see this file after logging in, you could set the Custom parameters field to the following string:

    [
      "next=/hub/user-redirect/git-pull?repo=https://github.com/binder-examples/requirements&subPath=index.ipynb",
    ];
    

    Note: If you have a base_url set in your jupyterhub configuration, that should be prefixed to your next parameter. (Further explanation)

  8. You are done! You can click the Link to see what the user workflow would look like. You can repeat step 6 in all the units that should have a link to the Hub for the user.

Canvas

The setup for Canvas is very similar to the process for edX.

Note: You will see Client Key and Consumer Key used interchangably.

Note: You will see Client Secret and Secret Key used interchangably.

  1. Create a client key and client secret for use by Canvas to authenticate your hub. Open up any command line:

    1. Run openssl rand -hex 32 and save the output. This will be your LTI Client Key.
    2. Run openssl rand -hex 32 and save the output. This will be your LTI Client Secret.

    Now we will use these strings to allow Canvas and JupyterHub to authenticate each other.

    Note: These commands will simply generate strings for you, it will not store them anywhere on the computer. Therefore you do not need to run these commands on your JupyterHub server--we will be supplying them manually in the next few steps.

    Note: Anyone with these two strings will be able to access your hub, so keep them secure!!

  2. Add a new external app configuration in Canvas. You can name it anything, but you'll be using it throughout Canvas to refer to your hub, so make it something meaningful and unique. Note that the right to create applications might be limited by your institution. The basic information required to create an application in Canvas' "Manual entry" mode is:

    • Name
    • Consumer Key - from step 1
    • Secret Key - from step 1
    • Launch URL - https://www.example.com/hub/lti/launch
    • Domain - optional
    • Privacy - anonymous, email only, name only, or public
    • Custom Fields - optional

    There are other configuration types, eg. "Paste XML" which offer more options.

    The application can be created at the account level or the course level. If the application is created at the account level, it means that the application is available to all courses under the same account.

    Privacy Setting:

    • If you run the course in public mode, ltiauthenticator will parse the student's canvas ID as the JupyterHub username.
    • If you run the course in anonymous mode, ltiauthenticator will fall back to the LTI user ID, an anonymized version.
      • Currently, the only method for de-anonymizing the LTI user ID in Canvas is with the "masquerade" permission, which grants the user full access to act as any user account.
      • Unless you are able to obtain masquerade permissions, it is recommended to run the course in public mode.
  3. Configure JupyterHub to accept LTI Launch requests from Canvas. You do this by supplying JupyterHub with the client key & secret generated in step 1.

    Note: While you could paste these keys directly into your configuration file, they are secure credentials and should not be committed to any version control repositories. It is therefore best practice to store them securely. Here, we have stored them in environment variables.

    c.JupyterHub.authenticator_class = 'ltiauthenticator.LTIAuthenticator'
    c.LTIAuthenticator.consumers = {
        os.environ['LTI_CLIENT_KEY']: os.environ['LTI_CLIENT_SECRET']
    }
    

    A Hub can be configured to accept Launch requests from multiple Tool Consumers. You can do so by just adding all the client keys & secrets to the c.LTIAuthenticator.consumers traitlet like above.

  4. Create a new assignment.

    1. Make the submission type an external tool
    2. IMPORTANT: Click "Find" and search for the tool you added in step 2. Click that and it will prepopulate the URL field with the one you supplied when creating the application. Using the "find" button to search for your tool is necessary to ensure the LTI key and secret are sent with the launch request.
    3. Check the "Launch in a new tab" checkbox.
    4. Append any custom parameters you wish (see next step)

    Note: If you are creating assignments via the Canvas API, you need to use these undocumented external tool fields when creating the assignment.

  5. Custom Parameters. Apart from any custom fields you have defined in step 2, you can add custom parameters to any assignment. Unlike EdX, there is no method to include these custom parameters in the lti launch request's form data. However, you can append custom parameters to the launch URL as query strings using proper character encoding to preserve the query strings as they are passed through JupyterHub. You can perform this encoding manually, programmatically, or via an online tool.

    Before:

    https://example.com/hub/lti/launch?custom_next=/hub/user-redirect/git-pull?repo=https://github.com/binder-examples/requirements&subPath=index.ipynb
    

    After:

    https://example.com/hub/lti/launch?custom_next=/hub/user-redirect/git-pull%3Frepo%3Dhttps%3A%2F%2Fgithub.com%2Fbinder-examples%2Frequirements%26subPath%3Dindex.ipynb
    

    Note that the entire query string should not need to be escaped, just the portion that will be invoked after JupyterHub processes the user-redirect command.

  6. You are done! You can click the link to see what the user workflow would look like. You can repeat step 7 in all the units that should have a link to the Hub for the user.

Moodle

The Moodle setup is very similar to both the examples outlined above.

  1. You need to be a Moodle Administrator, or have another Moodle Role that gives you Permissions to manage Activity Modules.

  2. You need to have enabled the 'External Tool' Activity Module in your Moodle environment

  3. Create an client-key for use by Moodle against your hub. You can do so by running openssl rand -hex 32 and saving the output.

  4. Create an client-secret for use by Moodle against your hub. You can do so by running openssl rand -hex 32 and saving the output.

  5. If you are running Jupyterhub locally, you need to Configure it to accept LTI Launch requests from Moodle. You do this by enabling the LTI Authenticator class and giving JupyterHub access to the client key & secret generated in steps 3 and 4.

    juptyerhub_config.py:

    c.JupyterHub.authenticator_class = 'ltiauthenticator.LTIAuthenticator'
    
    c.LTIAuthenticator.consumers = {
        "client-key": "client-secret"
    }
    
  6. If you are running Jupyterhub within a Kubernetes Cluster, deployed using helm, you need to supply the client key & secret via the chart yaml configuration.

    config.yaml:

    hub:
      config:
        LTIAuthenticator:
          consumers:
            client-key: client-secret
        JupyterHub:
          authenticator_class: ltiauthenticator.LTIAuthenticator
    
  7. If your Moodle environment is using https, you should also use https for your JupyterHub.

  8. Once you hub is up and running with the new LTI configuration, you can now configure Moodle.

  9. In the Moodle course you wish to add, turn on editing, and add an instance of the External Tool Activity Module (https://docs.moodle.org/37/en/External_tool_settings)

    Activtiy Name: This will be the name that appears in the course for students to click on to initiate the connection to your hub.

    Click 'Show more...'

    • Tool name:
    • Tool URL: Should be set to your-hub-url/hub/lti/launch. So if your hub is accessible at https://datahub.berkeley.edu, Tool URL should be https://datahub.berkeley.edu/hub/lti/launch.
    • Consumer Key: client key
    • Shared secret: client secret
    • Custom parameters:
    • Default launch container: This setting will define how the hub is presented to the student, whether it's embedded within a Moodle, with or without blocks, replaces the current window, or is displayed in a new window.
  10. Click 'Save and return to course' or 'Save and display', you will them either be returned to the course page, or have you hub displayed.

Common Gotchas

  1. If you have a base_url set in your jupyterhub configruation, this needs to be reflected in your launch URL and custom parameters. For example, if your jupyterhub_config.py file contains:

    `c.JupyterHub.base_url = '/jupyter'`
    

    then your Launch URL would be:

    https://www.example.com/jupyter/hub/lti/launch
    

    A custom next parameter might look like:

    [
      "next=/jupyter/hub/user-redirect/git-pull?repo=https://github.com/binder-examples/requirements&subPath=index.ipynb",
    ];
    
  2. [401 Unauthorized] - [Canvas] Make sure you added your JupyterHub link by first specifying the tool via the 'Find' button (Step 4.2). Otherwise your link will not be sending the appropriate key and secret and your launch request will be recognized as unauthorized.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jupyterhub-ltiauthenticator-1.1.0.tar.gz (17.4 kB view hashes)

Uploaded Source

Built Distribution

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page