Cvmcosta / ltijs

Turn your application into a fully integratable LTI 1.3 tool provider.
https://cvmcosta.github.io/ltijs/
Apache License 2.0
299 stars 67 forks source link

moodle request on /keys route fails: upgrade required #66

Closed zoranpopovic closed 3 years ago

zoranpopovic commented 3 years ago

Describe the bug when using ltijs-demo-server connecting to moodle server, ltijs provider is reachable upon setup, but neither grade nor class users action fails. When either grade is submitted, or roster is requested through demo-server frontend, Moodle fails on seemingly getting to ltijs jwks route, and then fails to parse the KeySet because it's null. Here are the moodle debug reports:

[php7:warn] [pid 200] [client 127.0.0.1:57740] PHP Warning: file_get_contents(https://ltijs.math.enlearn.org/keys): failed to open stream: HTTP request failed! HTTP/1.1 426 Upgrade Required
 in /bitnami/moodle/mod/lti/locallib.php on line 1365
[Wed Nov 25 18:14:35.225013 2020] [php7:notice] [pid 229] [client 127.0.0.1:37356] Default exception handler: Exception - Argument 1 passed to Firebase\\JWT\\JWK::parseKeySet() must be of the type array, null given, called in [dirroot]/mod/lti/locallib.php on line 1367 Debug: 
Error code: generalexceptionmessage
* line 35 of /lib/php-jwt/src/JWK.php: TypeError thrown
* line 1367 of /mod/lti/locallib.php: call to Firebase\\JWT\\JWK::parseKeySet()
* line 1422 of /mod/lti/locallib.php: call to lti_verify_with_keyset()
* line 71 of /mod/lti/token.php: call to lti_verify_jwt_signature()

ltijs with debug turned on reports:

2020-11-25T18:03:13.189Z provider:platform Valid access_token for https://moodle.math.enlearn.org not found 2020-11-25T18:03:13.190Z provider:platform Attempting to generate new access_token for https://moodle.math. 
2020-11-25T18:03:13.190Z provider:platform With scopes: https://purl.imsglobal.org/spec/lti-nrps/scope/cont 
2020-11-25T18:03:13.322Z provider:auth Awaiting return from the platform HTTPError: Response code 404 (Not Found)   
     at Request.<anonymous> (/app/node_modules/got/dist/source/as-promise/index.js:117:42)     
     at processTicksAndRejections (internal/process/task_queues.js:93:5) {                                   
       code: undefined,

Any idea why this would be? what does /keys route expect the protocol to be upgraded to?

Expected behavior Since platform seems to be correctly registered, and links work, something else is preventing basic reporting features to work.

Ltijs version latest

NodeJS version 14

Platform used Moodle latest

Additional context Add any other context about the problem here.

Cvmcosta commented 3 years ago

Hello! Can you tell me how your Platform and Tool are being hosted? If you are running your Tool locally (localhost) it needs to be accessible from your Platform.

I see that you are using Bitnami Moodle, if it's running in a docker container, requests to the keyset endpoint on localhost will not work. Moodle will try to call, for example, http://localhost:3000/keys, and localhost will not be accessible from inside the container.

zoranpopovic commented 3 years ago

Both are hosted in the same kubernetes cluster. Istio handles directing traffic from public addresses (e.g. moodle.example.com and ltijs.examle.com) down to specific ports of the containers for each. in the moodle logs above you can see that it's trying to reach file_get_contents(https://ltijs.math.enlearn.org/keys) so it is asking for keys at the right place.

Cvmcosta commented 3 years ago

Can you try to reach the keys endpoint from the browser and see if it returns the keys correctly?

zoranpopovic commented 3 years ago

moodle is setup via a standard bitnami helm chart, with these basic values:

    ingress:
      enabled: false
    moodlePassword: some-secret-pwd
    service:
      type: ClusterIP
    persistence.size: 2Gi
    mariadb.primary.persistence.size: 2Gi
zoranpopovic commented 3 years ago

They return keys without a problem.

Cvmcosta commented 3 years ago

If the endpoint is returning the keys correctly then the issue is with the communication between Platform and Tool. Your Platform is not capable of reaching your Tool.

The Keyset endpoint does not require any sort of input or authorization, if it is working correctly from the browser then the only possible issue is an inability to reach the endpoint.

I was not familiar with the HTTP/1.1 426 Upgrade Required error, but after some research i am confident that the issue is most likely not caused by the Ltijs server, but instead by the proxy redirecting requests to the express server Ltijs runs on.

zoranpopovic commented 3 years ago

Thanks for the help. I fixed the issue, but just in case someone else is stuck on something similar, moodle gets the keys with a php call file_get_contents(https://ltijs.example.com/keys), which is some archaic code that makes a http/1.0 call. Since my ltijs instance was running behind istio which by default does not allow this deprecated protocol, it just rejected it before getting to ltijs, asking for upgrade to http/1.1. Strangely, other moodle calls are not via http/1.0 just those with file_get_contents. Making istio accept 1.0 calls fixed the issue.

PanopticaRising commented 3 years ago

For anyone else who stumbles on this, I'm running a Windows -> Ubuntu -> Docker setup, and my issue was that initializing the tool connection happened on the Moodle website, but the later calls happened on the server, so an IP address didn't work for me (because the Docker container and my Windows machine are on different subnets). I was able to add a hostname to both to point to the respective IPs (172.17.0.1 on Docker and 127.0.0.1 on Windows) to get around the issue.

phiduo commented 2 years ago

For anyone else who stumbles on this, I'm running a Windows -> Ubuntu -> Docker setup, and my issue was that initializing the tool connection happened on the Moodle website, but the later calls happened on the server, so an IP address didn't work for me (because the Docker container and my Windows machine are on different subnets). I was able to add a hostname to both to point to the respective IPs (172.17.0.1 on Docker and 127.0.0.1 on Windows) to get around the issue.

Hi there, I am using a similar setup (Windows + moodle/bitnami docker container) and a second, independent setup (in a VM: Ubuntu + moodle/bitnami docker container) and when I try to connect an LTI tool both throw the same error:

Exception - Argument 1 passed to Firebase\JWT\JWK::parseKeySet() must be of the type array, null given, called in [dirroot]/mod/lti/locallib.php on line 1372

In moodle, when I click Select content on the Adding a new External tool page it successfully launches the tool, but any subsequent clicks in that tool lead to the error above. When the tool is displayed in the course it also just throws Invalid request.

I see you were able to solve your issue, do you happen to know any resources to point me to so I can get this resolved as well? Unfortunately, I am not that well-versed in Docker and don't see why IP addresses are the issue when Docker maps the ports anyway.

masterkain commented 11 months ago

forgot what I said -- I'm not running moodle locally so of course the moodle server can't reach my dev envs, I guess that's the issue.