WeBWorK Main Forum
Canvas LTI 1.3 authentification issue
- ◀︎ LTI 1.3 setup on Moodle
This forum has a limit to the number of forum postings you can make in a given time period - this is currently set at 10 posting(s) in 1 day
Re: Canvas LTI 1.3 authentification issue
by Peter Lert -Number of replies: 4
More on the Canvas LTI 1.3 story linking to WebWork version 2.18:
Indeed it appears that Canvas has coded a solution around the use of the default value for iss='https://canvas.instructure.com', in the common case that schools do not set up iss='https://myschool.instructure.com'. The Canvas repo in Github includes the following in 'canvas-lms/app/controllers/lti/ims/authentication_controller.rb':
# Redirect the "authorize" action for the domain specified
# in the lti_message_hint
#
# This means that tools can simply use the canvas.instructure.com
# domain in the authentication requests rather than keeping
# track of institution-specific domain.
def authorize_redirect
Utils::InstStatsdUtils::Timing.track "lti.authorize_redirect" do
redirect_to authorize_redirect_url
end
end
The GitHub file 'canvas-lms/spec/controllers/lti/ims/authentication_controller_spec.rb' indicates that in either of 2 contexts:
* when the developer key redirect uri contains a query string, or
* when the developer key redirect uri does not match [the value passed for the redirect_uri argument]
then Canvas will fail to authorize with an "Invalid redirect_uri" message. (I am not familiar with Ruby, so there may be other details that I am not seeing.) That's the error I am getting now. Here are the details:
Parameter settings in webwork2/conf/authen_LTI_1_3.conf:
$LTI{v1p3}{PlatformID} = 'https://canvas.instructure.com';
$LTI{v1p3}{ClientID} = '23xxx23';
$LTI{v1p3}{DeploymentID} = '31xxx63';
$LTI{v1p3}{PublicKeysetURL} = 'https://myuniv.instructure.com/api/lti/security/jwks';
$LTI{v1p3}{AccessTokenURL} = 'https://myuniv.instructure.com/login/oauth2/token';
$LTI{v1p3}{AccessTokenAUD} = 'https://myuniv.instructure.com/login/oauth2/token';
$LTI{v1p3}{AuthReqURL} = 'https://myuniv.instructure.com/api/lti/authorize_redirect';
Settings in Canvas Developer Key:
Redirect URIs = 'https://webwork.myuniv.edu/webwork2/ltiadvantage/launch'
Target Link URI = 'https://webwork.myuniv.edu/webwork2'
OpenID Connect Initiation Url = 'https://webwork.myuniv.edu/webwork2/ltiadvantage/login'
JWK Method = 'Public JWK URL'
Public JWK URL = 'https://webwork.myuniv.edu/webwork2/ltiadvantage/keys'
LTI Advantage Services All Selected
Additional Settings:
Domain = 'https://webwork.myuniv.edu'
Privacy level = Public
Placements:
Assignment Selection
Target Link URI Select Message Type LtiResourceLinkRequest
webwork2 debug.log:
===> Begin WeBWorK::dispatch() <===
[Tue Jul 23 18:19:29.970766 2024] (eval): Hi, I'm the new dispatcher!
[Tue Jul 23 18:19:29.971019 2024] (eval): --------------------------------------------------------------------------------
[Tue Jul 23 18:19:29.971205 2024] (eval): Okay, I got some basic information:
[Tue Jul 23 18:19:29.971397 2024] (eval): The site location is /webwork2
[Tue Jul 23 18:19:29.971581 2024] (eval): The request method is POST
[Tue Jul 23 18:19:29.971922 2024] (eval): The URI is /webwork2/ltiadvantage/login
[Tue Jul 23 18:19:29.972122 2024] (eval): The argument string is iss=https%3A%2F%2Fcanvas.instructure.com&login_hint=01xxx12&client_id=23xxx23&deployment_id=31xxx63&target_link_uri=https%3A%2F%2Fwebwork.myuniv.edu%2Fwebwork2%2FMATH_321<i_message_hint=eyJxxxXoo&canvas_environment=prod&canvas_region=us-east-1<i_storage_target=post_message_forwarding
[Tue Jul 23 18:19:29.972295 2024] (eval): --------------------------------------------------------------------------------
[Tue Jul 23 18:19:29.972570 2024] (eval): The path is /ltiadvantage/login/
[Tue Jul 23 18:19:29.972777 2024] (eval): The current route is ltiadvantage_login
[Tue Jul 23 18:19:29.972942 2024] (eval): Here is some information about this route:
[Tue Jul 23 18:19:29.973596 2024] (eval): The display module for this route is WeBWorK::ContentGenerator::LTIAdvantage
[Tue Jul 23 18:19:29.973804 2024] (eval): This route has the following captures:
[Tue Jul 23 18:19:29.974029 2024] (eval): action => login
[Tue Jul 23 18:19:29.974197 2024] (eval): controller => LTIAdvantage
[Tue Jul 23 18:19:29.974361 2024] (eval): courseID => MATH_321
[Tue Jul 23 18:19:29.974550 2024] (eval): --------------------------------------------------------------------------------
[Tue Jul 23 18:19:29.974713 2024] (eval): Now we want to look at the parameters we got.
[Tue Jul 23 18:19:29.974898 2024] (eval): The raw params:
[Tue Jul 23 18:19:29.975107 2024] (eval): login_hint => "01xxx12"
[Tue Jul 23 18:19:29.975289 2024] (eval): client_id => "23xxx23"
[Tue Jul 23 18:19:29.975469 2024] (eval): target_link_uri => "https://webwork.myuniv.edu/webwork2/MATH_321"
[Tue Jul 23 18:19:29.975646 2024] (eval): deployment_id => "31xxx63"
[Tue Jul 23 18:19:29.975838 2024] (eval): lti_storage_target => "post_message_forwarding"
[Tue Jul 23 18:19:29.976013 2024] (eval): canvas_region => "us-east-1"
[Tue Jul 23 18:19:29.976128 2024] (eval): iss => "https://canvas.instructure.com"
[Tue Jul 23 18:19:29.976199 2024] (eval): lti_message_hint => "eyJxxxwc8"
[Tue Jul 23 18:19:29.976280 2024] (eval): canvas_environment => "prod"
[Tue Jul 23 18:19:29.976348 2024] (eval): --------------------------------------------------------------------------------
[Tue Jul 23 18:19:29.976414 2024] (eval): We need to get a course environment (with or without a courseID!)
[Tue Jul 23 18:19:29.986535 2024] (eval): Here's the course environment: WeBWorK::CourseEnvironment=HASH(0x55XXXf0)
[Tue Jul 23 18:19:29.987044 2024] (eval): Using user_authen_module WeBWorK::Authen::LTIAdvantage: WeBWorK::Authen::LTIAdvantage=HASH(0x55XXX08)
[Tue Jul 23 18:19:29.987162 2024] (eval): We got a courseID from the route, now we can do some stuff:
[Tue Jul 23 18:19:29.987233 2024] (eval): ...we can create a database object...
[Tue Jul 23 18:19:29.994696 2024] (eval): (here's the DB handle: WeBWorK::DB=HASH(0x55XXX88))
[Tue Jul 23 18:19:29.995016 2024] WeBWorK::Authen::LTIAdvantage::verify: The LTI Advantage login route was accessed with the appropriate parameters.
===> end of log <===
In a Canvas course I used the WebWork LTI 1.3 tool installed with the Developer Key above to create and save a Canvas Assignment linked to a WebWork version 2.18 course MATH_321. When this assignment is selected Canvas responds with a button to "Load MATH_321 in a new window". However when that link is selected the result in Canvas is:
{"status":"bad_request","message":"Invalid redirect_uri"}
and the address box for the browser window with that error message shows the following (with redactions):
'https://myuniv.instructure.com/api/lti/authorize?client_id=23xxx23&login_hint=01xxx12<i_message_hint=eyJxxxwc8&nonce=415xxxaa0&prompt=none&redirect_uri=http%3A%2F%2Fwebwork.myuniv.edu%2Fwebwork2%2Fltiadvantage%2Flaunch&response_mode=form_post&response_type=id_token&scope=openid&state=01dxxx112%2Cset_id%3AMATH_321%2Cset_id%3Afafxxx141'
Thewebwork2 debug.log listed above results from this attempt to access WebWork from my Canvas course.
The single anomaly I can spot is that the value provided for the redirect_uri parameter shown in Canvas is:
redirect_uri=http%3A%2F%2Fwebwork.myuniv.edu%2Fwebwork2%2Fltiadvantage%2Flaunch
which is equivalent to:
redirect_uri=http://webwork.myuniv.edu/webwork2/ltiadvantage/launch
This value for the redirect_uri argument in Canvas differs from the value given in the Developer Key for Redirect URIs in that it substitutes 'http' for 'https'. Any idea where that change occurs, or why?
More importantly, and idea on how to fix this?
Again, if anyone can share the details of their successful Canvas/WebWork v2.18 LTI 1.3 configuration details (appropriately redacted) we will greatly appreciate it.
Permalink Show parent Reply
In reply to Peter Lert
Re: Canvas LTI 1.3 authentification issue
by Glenn Rice -As I said, the PlatformID "may" need to be the institution specific instructure URL ... but maybe not. I know that in testing with the docker build of Canvas from Github I needed to specifically use "https://canvas.instructure.com". I haven't tested on a production instance of Canvas though.
The change from "https" to "http" is happening on line 159 of lib/WeBWorK/ContentGenerator/LTIAdvantage.pm. You don't have your webwork2 server configured correctly to serve with SSL. How are you serving webwork? Are you serving directly via hypnotoad, or are you proxying via another server (like apache2)?
Permalink Show parent Reply
In reply to Glenn Rice
Re: Canvas LTI 1.3 authentification issue
by Thomas Mullaly -We use nginx as a web proxy on a separate server for a number of internal web sites and applications, including our production webwork 2.16 server.
Our webwork 2.18 server is also behind this same web proxy. I didn't bother using a local proxy on the webwork server itself for this server, hypnotoad is listening to the external interface and the web proxy talks to it on the local subnet. The web proxy has the ssl connection to the client, the connection from the web proxy to the hypnotoad app is not encrypted. The firewall rules on the webwork server are set to only allow connections from the web proxy.
thoughts?
-tom
Permalink Show parent Reply
In reply to Thomas Mullaly
Re: Canvas LTI 1.3 authentification issue
by Glenn Rice -Then the problem is that the proxy is not configured to forward the protocol. So Mojolicious doesn't think that SSL is in use. As such, when url_for is called on line 159 of lib/WeBWorK/ContentGenerator/LTIAdvantage.pm, it gives a URL with http instead of https. You should look at the /opt/webwork/webwork2/conf/webwork2.nginx.dist.conf file. It has the nginx configuration that forwards the protocol in it. That is the line proxy_set_header X-Forwarded-Proto $scheme;
.
Permalink Show parent Reply
In reply to Glenn Rice
Re: Canvas LTI 1.3 authentification issue
by Thomas Mullaly -Thanks, that has fixed the issue. I added this to my nginx config:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
Permalink Show parent Reply
- ◀︎ LTI 1.3 setup on Moodle
◀︎ Announcements
WeBWorK Problems ▶︎