From b28b5bf4d4afa47cf2beb1e3814c428eb4b1fa52 Mon Sep 17 00:00:00 2001 From: Xander Moffatt Date: Mon, 27 Mar 2023 13:22:52 -0600 Subject: [PATCH] add canvas_environment to LTI 1.3 login request why: * so that LTI 1.3 tools can redirect to different domain or launch url if desired closes INTEROP-8009 flag=none test plan: * launch the lti 1.3 test tool * find the /login request or install the LTI debugger Firefox extension * the login request should contain canvas_environment: prod * add a new `testcluster.yml` file to the `config` directory * add `test_cluster_name: 'beta'` to that file * in a rails console, run ` Setting.set('allow_tc_access_', 'true') * restart the canvas web container * relaunch the tool * the login request should contain canvas_environment: beta Change-Id: Ic58b6c5ba56a1da7f71bd202afff0c12aed9a70c Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/314295 Tested-by: Service Cloud Jenkins Reviewed-by: Tucker Mcknight QA-Review: Tucker Mcknight Product-Review: Alexis Nast --- app/models/lti/lti_advantage_adapter.rb | 1 + doc/api/fulldoc/html/css/common.css | 2 +- doc/api/lti_dev_key_config.md | 82 ++++++++++++++++++- doc/api/tools_xml.md | 6 +- .../lti_advantage/messages/login_request.rb | 1 + .../application_controller_spec.rb | 1 + .../external_tools_controller_spec.rb | 1 + spec/controllers/users_controller_spec.rb | 1 + spec/models/lti/lti_advantage_adapter_spec.rb | 25 ++++++ 9 files changed, 116 insertions(+), 4 deletions(-) diff --git a/app/models/lti/lti_advantage_adapter.rb b/app/models/lti/lti_advantage_adapter.rb index df4c22f8722..eb5ffc2d8c5 100644 --- a/app/models/lti/lti_advantage_adapter.rb +++ b/app/models/lti/lti_advantage_adapter.rb @@ -182,6 +182,7 @@ module Lti deployment_id: @tool.deployment_id, target_link_uri: target_link_uri, lti_message_hint: message_hint, + canvas_environment: ApplicationController.test_cluster_name || "prod", canvas_region: @context.shard.database_server.config[:region] || "not_configured" ) req.lti_storage_target = Lti::PlatformStorage.lti_storage_target if @include_storage_target diff --git a/doc/api/fulldoc/html/css/common.css b/doc/api/fulldoc/html/css/common.css index 8e43e30589f..8253ee38c78 100644 --- a/doc/api/fulldoc/html/css/common.css +++ b/doc/api/fulldoc/html/css/common.css @@ -268,7 +268,7 @@ h2 .defined-in { } table { - border: 1px solid red; + border: 1px solid gray; border-collapse: collapse; } diff --git a/doc/api/lti_dev_key_config.md b/doc/api/lti_dev_key_config.md index b03c2ac8292..cdee8800c34 100644 --- a/doc/api/lti_dev_key_config.md +++ b/doc/api/lti_dev_key_config.md @@ -33,6 +33,67 @@ Canvas iss + The issuer, as described above. + + + login_hint + Opaque value that must be passed back to Canvas in the next step. + + + target_link_uri + The recommended final redirect for the tool; not required. + + + client_id + The OAuth2 client id, or Developer Key id, for convenience. + + + deployment_id + Unique identifier for the specific deployment of this tool, for convenience. + + + canvas_region + For hosted Canvas, the AWS region (e.g. us-east-1) in which the institution that provided this token resides. For local or open source Canvas, this will have a value of "unknown". This field is safe to ignore. This can be used for tools that are hosted in multiple regions to launch to one url and redirect to the correct region. + + + canvas_environment + For hosted Canvas, the environment (e.g. "production", "beta", or "test") from which the tool is being launched. For local or open source Canvas, this will have a value of "production". This field is safe to ignore. Tools can use this to redirect to beta- or test-specific instances of their tool on launch. This is in place of the LTI 1.1 `environments` tool config option, which is not recognized for 1.3 tools. + + + + + +####Step 1.5: Optional Tool-to-tool Redirect + +There are situations where a tool wants to use a region-specific or environment-specific instance of itself to respond to the LTI launch, like keeping traffic within the same region as the instance of Canvas, or using a different domain or even launch URL when launched from beta Canvas vs normal production. + +Tools can use the `canvas_region` or `canvas_environment` parameters specified above, or even the Canvas URL from the request's referrer, to decide if they want to redirect. + +Example of redirecting to a different domain based on region and environment: + +- Login request is made to the tool's OIDC initiation URL, `mytool.net/login`, and contains `canvas_region: us-west-2, canvas_environment: beta`. +- The tool redirects to `beta-pdx.mytool.net/login`, forwarding all of the request parameters. +- The beta-pdx instance of the tool responds by continuing on to Step 2 below. + +Example of redirecting to a different launch URL based on environment: + +- Login request is made to the tool's OIDC initiation URL, `mytool.net/login`, and contains `canvas_environment: beta, target_link_uri: mytool.net/launch`. +- The tool continues on to Step 2 below, but sends `redirect_uri: mytool.net/beta_launch` instead of using the target_link_uri. + +Tools that wish to utilize this redirect need to make sure that all possible initiation URLs, whether the domains or paths vary, are added to the redirect URIs list on their corresponding Developer Key, so that the auth request in Step 2 succeeds. + +Tools that utilize different instances for beta and test must also make sure that they are storing the correct corresponding values for Canvas URLS like the OIDC Auth URL, JWKs URL, and the Issuer/`iss`, and that they use the beta or test versions of all of those URLs when the tool is launched from beta or test Canvas. + ###Step 2: Authentication Request To complete authentication, tools are expected to send back an authentication request to an "OIDC Authorization end-point". This can be a GET or POST, however, this request needs to be a redirect in the user’s browser and not made server to server as we need to validate the current user's session data. For cloud-hosted Canvas, regardless of the domain used by the client, the endpoint is always: @@ -97,7 +158,8 @@ Tools will need to be aware of some Canvas-specific settings in order to accept - Beta: `https://canvas.beta.instructure.com/api/lti/security/jwks` - Test: `https://canvas.test.instructure.com/api/lti/security/jwks` -- **Authorization Redirect URL**: The values and use of this are described in [Step 2](#step-2). Since the URL is static, you will want to configure this in your tool. +- **Authorization Redirect URL**: The values and use of this are described in [Step 2](#step-2). Since the URL is static, you will want to configure this in your tool. Tools that wish to utilize [Step 1.5](#login-redirect) need to include _all_ possible + redirect URLs here. - **Client ID**: The `client_id` of the Developer Key that's been configured in Canvas. Your tool will need to use this in the authentication response to Canvas ([Step 2](#step-2)) and it is also used during the Client Credentials Grant to access LTI Advantage Services. @@ -555,6 +617,24 @@ object for placement-specific target_link_uri's

+ + + + environments + + Ignored + + JSON object + + +

LTI 1.1 tools support enviroment-specific domains and launch urls, used for launching + from beta or test instances of Canvas. This config option is not supported for LTI 1.3. Tools instead should use the + canvas_environment parameter of the OIDC Login request to redirect to environment-specific launch urls or + instances of the tool, as specified in Step 1.5 above. +

+ + + diff --git a/doc/api/tools_xml.md b/doc/api/tools_xml.md index bec91cc853b..4c5030ecfd7 100644 --- a/doc/api/tools_xml.md +++ b/doc/api/tools_xml.md @@ -532,6 +532,9 @@ matching, and to only return URLs matching that domain. External tools can support different LTI environments for different canvas environments. +NOTE: This setting is only supported by LTI 1.1 tools. LTI 1.3 tools should redirect to the +desired domain/launch URL as described in the LTI 1.3 configuration guide. + * __domain__: All url domains in this tool's configuration will be replaced with this domain * __launch_url__: the blti:launch\_url property that should be used for all canvas test environments. This property takes precedent over domain changes if both properties are set. @@ -541,8 +544,7 @@ by specifying the environment as part of the property name (ie, test\_launch\_ur beta\_domain, etc). When used in this manner, specific environment properties take precedent over the default values. -NOTE: Test environment settings are established during the refresh process when the environments are -mirrored from production. +These settings will be applied dynamically during the launch process. ### Test Environment Example diff --git a/gems/lti-advantage/lib/lti_advantage/messages/login_request.rb b/gems/lti-advantage/lib/lti_advantage/messages/login_request.rb index 18c27cbf79a..13a3b9927fc 100644 --- a/gems/lti-advantage/lib/lti_advantage/messages/login_request.rb +++ b/gems/lti-advantage/lib/lti_advantage/messages/login_request.rb @@ -30,6 +30,7 @@ module LtiAdvantage::Messages OPTIONAL_PARAMETERS = %i[ lti_message_hint canvas_region + canvas_environment client_id lti_storage_target deployment_id diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 05248f5d890..c5bc9e25586 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -1124,6 +1124,7 @@ RSpec.describe ApplicationController do target_link_uri lti_message_hint canvas_region + canvas_environment client_id deployment_id lti_storage_target diff --git a/spec/controllers/external_tools_controller_spec.rb b/spec/controllers/external_tools_controller_spec.rb index 26595452b9d..93004e7ed17 100644 --- a/spec/controllers/external_tools_controller_spec.rb +++ b/spec/controllers/external_tools_controller_spec.rb @@ -155,6 +155,7 @@ describe ExternalToolsController do target_link_uri lti_message_hint canvas_region + canvas_environment client_id deployment_id lti_storage_target diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 9bebb29c9a2..56090e3c876 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -111,6 +111,7 @@ describe UsersController do target_link_uri lti_message_hint canvas_region + canvas_environment client_id deployment_id lti_storage_target diff --git a/spec/models/lti/lti_advantage_adapter_spec.rb b/spec/models/lti/lti_advantage_adapter_spec.rb index 6c01f950fa5..d0314942807 100644 --- a/spec/models/lti/lti_advantage_adapter_spec.rb +++ b/spec/models/lti/lti_advantage_adapter_spec.rb @@ -134,6 +134,7 @@ describe Lti::LtiAdvantageAdapter do target_link_uri lti_message_hint canvas_region + canvas_environment client_id deployment_id lti_storage_target @@ -187,6 +188,30 @@ describe Lti::LtiAdvantageAdapter do expect(login_message["canvas_region"]).to eq "not_configured" end + it 'sets the "canvas_environment" to "prod"' do + expect(login_message["canvas_environment"]).to eq "prod" + end + + context "when in beta" do + before do + allow(ApplicationController).to receive(:test_cluster_name).and_return("beta") + end + + it 'sets "canvas_enviroment" to "beta"' do + expect(login_message["canvas_environment"]).to eq "beta" + end + end + + context "when in test" do + before do + allow(ApplicationController).to receive(:test_cluster_name).and_return("test") + end + + it 'sets "canvas_enviroment" to "test"' do + expect(login_message["canvas_environment"]).to eq "test" + end + end + it "accepts a student_id parameter" do expect(adapter.generate_post_payload(student_id: 123).keys).to include("iss") end