WeBWorK Main Forum

LTI 1.3 Moodle authentication

LTI 1.3 Moodle authentication

by Sean Fitzpatrick -
Number of replies: 10

We are trying to get LTI 1.3 set up again on Moodle. I have LTI 1.1 with deep linking working fine.

Secure cookies are enabled, with same site cookies set to lax.

When clicking the "select content" button in the external tool setup, I get a login page. (For some strange reason, I am getting the login page for a Fall 2024 computer science course that I am not an instructor for.)

This persists across devices and browsers.

The end of the debug log reads as follows:

[Wed Jul 09 11:36:31.395881 2025] (eval): We need to get a course environment (with or without a courseID!)

[Wed Jul 09 11:36:31.402979 2025] (eval): Here's the course environment: WeBWorK::CourseEnvironment=HASH(0x614b7d4a0690)

[Wed Jul 09 11:36:31.403552 2025] (eval): Using authentication module WeBWorK::Authen::LTIAdvanced: WeBWorK::Authen::LTIAdvanced=HASH(0x614b7d4fab90)

[Wed Jul 09 11:36:31.403711 2025] (eval): We got a courseID from the route, now we can do some stuff:

[Wed Jul 09 11:36:31.403817 2025] (eval): ...we can create a database object...

[Wed Jul 09 11:36:31.395881 2025] (eval): We need to get a course environment (with or without a courseID!)

[Wed Jul 09 11:36:31.402979 2025] (eval): Here's the course environment: WeBWorK::CourseEnvironment=HASH(0x614b7d4a0690)

[Wed Jul 09 11:36:31.403552 2025] (eval): Using authentication module WeBWorK::Authen::LTIAdvanced: WeBWorK::Authen::LTIAdvanced=HASH(0x614b7d4fab90)

[Wed Jul 09 11:36:31.403711 2025] (eval): We got a courseID from the route, now we can do some stuff:

[Wed Jul 09 11:36:31.403817 2025] (eval): ...we can create a database object...

[Wed Jul 09 11:36:31.416907 2025] (eval): (here's the DB handle: WeBWorK::DB=HASH(0x614b7d472bf8))

[Wed Jul 09 11:36:31.417189 2025] WeBWorK::Authen::verify: BEGIN VERIFY

[Wed Jul 09 11:36:31.417320 2025] WeBWorK::Authen::LTIAdvanced::request_has_data_for_this_verification_module: LTIAdvanced has been called for data verificat>

[Wed Jul 09 11:36:31.417419 2025] WeBWorK::Authen::LTIAdvanced::request_has_data_for_this_verification_module: LTIAdvanced returning that it is not configure>

[Wed Jul 09 11:36:31.417855 2025] WeBWorK::Authen::verify: BEGIN VERIFY

[Wed Jul 09 11:36:31.417997 2025] WeBWorK::Authen::do_verify: db ok

[Wed Jul 09 11:36:31.418098 2025] WeBWorK::Authen::get_credentials: self is WeBWorK::Authen::Basic_TheLastOption=HASH(0x614b7d4cd890)

[Wed Jul 09 11:36:31.418619 2025] WeBWorK::Authen::fetchCookie: fetchCookie: Session cookie does not contain valid information. Returning nothing.

[Wed Jul 09 11:36:31.416907 2025] (eval): (here's the DB handle: WeBWorK::DB=HASH(0x614b7d472bf8))


In reply to Sean Fitzpatrick

Re: LTI 1.3 Moodle authentication

by Sean Fitzpatrick -
I caught a mistake: in authen_LTI.conf, in the line $authen{user_module}, I forgot to uncomment the LTI 1.3 line.
Right now I'm including the conf files for both LTI 1.1 and LTI 1.3, since we have 1.1 working and I don't want to break it.

Progress, sort of. Instead of being taken to the login page for a random course, I get "No WeBWorK course was found associated to this LMS course. If this is an error, please contact the WeBWorK system administrator." on the Select Content page, but no further parameters I can use.
In reply to Sean Fitzpatrick

Re: LTI 1.3 Moodle authentication

by Sean Fitzpatrick -
Here's what is generated in debug.log when I click the select content button. Last year we suspected that the issue was due to having multiple public keys behind a load balancer. Our LMS admins don't think that's an issue since they have other LTI 1.3 connections that are working correctly.

Some lines below are too long and get cut off. I am also going to redact the client ID.

===> Begin WeBWorK::dispatch() <===

[Wed Jul 09 12:17:52.896904 2025] (eval): Hi, I'm the new dispatcher!
[Wed Jul 09 12:17:52.897039 2025] (eval): --------------------------------------------------------------------------------
[Wed Jul 09 12:17:52.897203 2025] (eval): Okay, I got some basic information:
[Wed Jul 09 12:17:52.897308 2025] (eval): The site location is /webwork2
[Wed Jul 09 12:17:52.897394 2025] (eval): The request method is POST
[Wed Jul 09 12:17:52.897725 2025] (eval): The URI is /webwork2/ltiadvantage/login
[Wed Jul 09 12:17:52.897854 2025] (eval): The argument string is iss=https%3A%2F%2Fmoodle.uleth.ca&target_link_uri=https%3A%2F%2Fwebwork.uleth.ca%2Fwebwork2%> [Wed Jul 09 12:17:52.897981 2025] (eval): --------------------------------------------------------------------------------
[Wed Jul 09 12:17:52.898180 2025] (eval): The path is /ltiadvantage/login/
[Wed Jul 09 12:17:52.898339 2025] (eval): The current route is ltiadvantage_login
[Wed Jul 09 12:17:52.898458 2025] (eval): Here is some information about this route:
[Wed Jul 09 12:17:52.898561 2025] (eval): The display module for this route is WeBWorK::ContentGenerator::LTIAdvantage
[Wed Jul 09 12:17:52.898643 2025] (eval): This route has the following captures:
[Wed Jul 09 12:17:52.898737 2025] (eval): action => login
[Wed Jul 09 12:17:52.898822 2025] (eval): controller => LTIAdvantage
[Wed Jul 09 12:17:52.898903 2025] (eval): --------------------------------------------------------------------------------
[Wed Jul 09 12:17:52.899015 2025] (eval): Now we want to look at the parameters we got.
[Wed Jul 09 12:17:52.899104 2025] (eval): The raw params:
[Wed Jul 09 12:17:52.899315 2025] (eval): lti_message_hint => "{"launchid":"ltilaunch_ContentItemSelectionRequest458891602"}"
[Wed Jul 09 12:17:52.899418 2025] (eval): target_link_uri => "https://webwork.uleth.ca/webwork2/ltiadvantage/content_selection"
[Wed Jul 09 12:17:52.899506 2025] (eval): lti_deployment_id => "264"
[Wed Jul 09 12:17:52.899614 2025] (eval): client_id => "(redacted)"
[Wed Jul 09 12:17:52.899709 2025] (eval): login_hint => "44723"
[Wed Jul 09 12:17:52.899793 2025] (eval): iss => "https://moodle.uleth.ca"
[Wed Jul 09 12:17:52.899872 2025] (eval): --------------------------------------------------------------------------------
[Wed Jul 09 12:17:52.926675 2025] (eval): We need to get a course environment (with or without a courseID!)
[Wed Jul 09 12:17:52.933550 2025] (eval): Here's the course environment: WeBWorK::CourseEnvironment=HASH(0x56d27d5cfba8)
[Wed Jul 09 12:17:52.980362 2025] (eval): Using authentication module WeBWorK::Authen::LTIAdvantage: WeBWorK::Authen::LTIAdvantage=HASH(0x56d27d6768f8)
[Wed Jul 09 12:17:52.980579 2025] (eval): We got a courseID from the route, now we can do some stuff:
[Wed Jul 09 12:17:52.980727 2025] (eval): ...we can create a database object...
[Wed Jul 09 12:17:53.21584 2025] (eval): (here's the DB handle: WeBWorK::DB=HASH(0x56d27d51e6e0))
[Wed Jul 09 12:17:53.22107 2025] WeBWorK::Authen::LTIAdvantage::verify: The LTI Advantage login route was accessed with the appropriate parameters.
[Wed Jul 09 12:17:53.137644 2025] (eval):

===> Begin WeBWorK::dispatch() <===

[Wed Jul 09 12:17:53.137860 2025] (eval): Hi, I'm the new dispatcher!
[Wed Jul 09 12:17:53.137979 2025] (eval): --------------------------------------------------------------------------------
[Wed Jul 09 12:17:53.138072 2025] (eval): Okay, I got some basic information:
[Wed Jul 09 12:17:53.138178 2025] (eval): The site location is /webwork2
[Wed Jul 09 12:17:53.138314 2025] (eval): The request method is POST
[Wed Jul 09 12:17:53.138479 2025] (eval): The URI is /webwork2/ltiadvantage/launch
[Wed Jul 09 12:17:53.138578 2025] (eval): The argument string is id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ijk2YzIyNGJhZThjNDdkMTJhMTYwIn0.eyJub25> [Wed Jul 09 12:17:53.138767 2025] (eval): --------------------------------------------------------------------------------
[Wed Jul 09 12:17:53.138921 2025] (eval): The path is /ltiadvantage/launch/
[Wed Jul 09 12:17:53.139048 2025] (eval): The current route is ltiadvantage_launch
[Wed Jul 09 12:17:53.139150 2025] (eval): Here is some information about this route:
[Wed Jul 09 12:17:53.139247 2025] (eval): The display module for this route is WeBWorK::ContentGenerator::LTIAdvantage
[Wed Jul 09 12:17:53.139333 2025] (eval): This route has the following captures:
[Wed Jul 09 12:17:53.139419 2025] (eval): controller => LTIAdvantage
[Wed Jul 09 12:17:53.139503 2025] (eval): action => launch
[Wed Jul 09 12:17:53.139586 2025] (eval): --------------------------------------------------------------------------------
[Wed Jul 09 12:17:53.139669 2025] (eval): Now we want to look at the parameters we got.
[Wed Jul 09 12:17:53.139751 2025] (eval): The raw params:
[Wed Jul 09 12:17:53.139894 2025] (eval): state => "2ad606151370160aab94c1cd75ab76b2eb335446175d72627b1bf1c5768fc1e5"
[Wed Jul 09 12:17:53.140009 2025] (eval): id_token => "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ijk2YzIyNGJhZThjNDdkMTJhMTYwIn0.eyJub25jZSI6ImRlNDZi> [Wed Jul 09 12:17:53.140168 2025] (eval): --------------------------------------------------------------------------------
[Wed Jul 09 12:17:53.332722 2025] (eval): We need to get a course environment (with or without a courseID!)
[Wed Jul 09 12:17:53.339936 2025] (eval): Here's the course environment: WeBWorK::CourseEnvironment=HASH(0x56d275622508)
[Wed Jul 09 12:17:53.340498 2025] (eval): Using authentication module WeBWorK::Authen::LTIAdvantage: WeBWorK::Authen::LTIAdvantage=HASH(0x56d27d9e0378)
In reply to Sean Fitzpatrick

Re: LTI 1.3 Moodle authentication

by Glenn Rice -

What browser are you using?  Often this issue is caused by cookies being rejected by the browser.  The browser that is most notorious for this is Google Chrome.  In fact, in my testing I have found no work around for this.  In Firefox and Safari it is possible to change your browser settings so that cookies are not rejected.  You need to make sure that third party cookies are not blocked.  I believe that in Firefox the "Standard" setting allows these cookies, but I may be mistaken.  In Safari the setting is "Prevent Cross-Site Tracking".  You need to make sure that setting is disabled.

There are some other possible causes of this.  The debug log you posted does not seem complete.  There should be more after the last line shown.  Since you are reaching the /webwork2/ltiadvantage/launch route, I suspect that cookies are the issue, but what should be after the last line you showed should reveal more.  You should also set $debug_lti_parameters in authen_LTI.conf, and look in the logs/webwork2.log file to see if that shows anything.

In reply to Glenn Rice

Re: LTI 1.3 Moodle authentication

by Sean Fitzpatrick -
I was using Chrome, but it is set to allow third party cookies. But I just tried Firefox as well. Firefox has "enhanced tracking protection" on by default, but I disabled it for Moodle and I still get the same result.
(However, I tried a different LTI 1.3 tool, and it told me my browser was blocking cookies, even after I disabled blocking of cookies globally...)
I have $debug_lti_parameters=1 and I've got the debugging turned on in the webwork2.mojolicious.yml file as well.

After trying to select content on Moodle, I get the following tail from webwork2.log:

[2025-07-09 13:45:14.75358] [174737] [info] Worker 174737 started
[2025-07-09 13:45:14.75818] [174738] [info] Worker 174738 started
[2025-07-09 13:45:14.76273] [174739] [info] Worker 174739 started
[2025-07-09 13:45:14.76741] [174740] [info] Worker 174740 started
[2025-07-09 13:45:14.77185] [174741] [info] Worker 174741 started
[2025-07-09 13:45:14.77629] [174742] [info] Worker 174742 started
[2025-07-09 13:45:14.78092] [174743] [info] Worker 174743 started
[2025-07-09 13:45:14.78491] [174643] [info] Creating process id file "/run/webwork2/webwork2.pid"
[2025-07-09 13:45:14.78533] [174744] [info] Worker 174744 started
[2025-07-09 13:45:29.03303] [174744] [warn] [Y19cCtVaf4Ne] [/webwork2/ltiadvantage/login] The LTI Advantage login route was accessed with the appropriate parameters.

And if I tail debug.log, the last line is the same as above, but with a different hash.
In reply to Sean Fitzpatrick

Re: LTI 1.3 Moodle authentication

by Sean Fitzpatrick -

Related: in the authen_LTI_1_3.conf file, can I enable more than one LMS?

We're on Moodle, but this is our last year with our current Moodle host, and we're trialling D2L.

I don't see anything in my config files that could be causing the log files to be truncated.

In reply to Glenn Rice

Re: LTI 1.3 Moodle authentication

by Sean Fitzpatrick -
I am also trying (and failing) to set up LTI 1.3 for Runestone, and the logs there indicate that it is failing because it can't parse the public key provided by Moodle.
Maybe this is because of the load balancer being used for Moode? They have LTI 1.3 working for TurnItIn so they thought it should work fine for other apps.
In reply to Sean Fitzpatrick

Re: LTI 1.3 Moodle authentication

by Sean Fitzpatrick -
Sorry, I was wrong about this: the problem was with the public key on Runestone, not on Moodle.

But this leads to another question: LTI 1.3 was only very recently added on Runestone. One step that is necessary is generating a public/private key pair. But WeBWorK doesn't seem to need this. Also, with LTI advantage, we should just be able to click the "Activate" button in Moodle, as in these Runestone instructions, to configure things. The process for WeBWorK seems so much more involved on both the Moodle and WeBWorK ends.
In reply to Sean Fitzpatrick

Re: LTI 1.3 Moodle authentication

by Glenn Rice -

I am not sure what you mean.

The public/private key that is generated is certainly needed by WeBWorK.  But that is not a step that you do.  That is done automatically by WeBWorK.

If you would like to implement something like what Runestone has, then please do so.

In reply to Glenn Rice

Re: LTI 1.3 Moodle authentication

by Sean Fitzpatrick -
I am fine with any setup that gets me past the "No WeBWorK course was found" message.

I feel like we have tried everything, and nothing has worked. If there is more information I can provide, please let me know.

Everything is configured exactly like it says in the Wiki, and I've been through every LTI 1.3 thread on this forum.
In reply to Glenn Rice

Re: LTI 1.3 Moodle authentication

by Sean Fitzpatrick -
Is there any sort of incantation I can use to get the missing lines from the log file?
I've spent the entire day adjusting configuration settings, restarting webwork2, and trying to launch an LTI 1.3 tool, and the debug.log file always ends up the same as above.

Debugging is turned on in the LTI config and the mojolicious config. I'm checking both webwork2.log and debug.log, and I keep getting the same sort of thing.