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

Issue running litjs and mongodb in docker-compose #142

Closed Maxvanhattum closed 2 years ago

Maxvanhattum commented 2 years ago

Describe the bug When running the LTI tool with MongoDB in docker-containers, the application cannot process the idtoken. It seems to be able to process the LTI handshake, but then after the redirect to my application path it cannot process that token.

{
   "status":401,
   "error":"Unauthorized",
   "details":{
      "description":"Error validating ltik or IdToken",
      "message":"connect ECONNREFUSED 127.0.0.1:80"
   }
}

This seems to be a configuration problem with the use of mongoose (I think), however the strange thing is that it does connect properly on starting the LTI with registering the platform. The same application does work when running a local mongodb instance and npm run start.

Expected behavior Should be able to process the idtoken after login flow has been completed and redirection happened.

Provider logs

lti-gateway    | 2022-02-24T11:59:53.813Z provider:main Receiving request at path: /
lti-gateway    | 2022-02-24T11:59:53.813Z provider:main Path does not match reserved endpoints
lti-gateway    | 2022-02-24T11:59:53.813Z provider:main Cookies received: 
lti-gateway    | 2022-02-24T11:59:53.814Z provider:main [Object: null prototype] {
lti-gateway    |   'ltiaHR0cHM6Ly9jYW52YXMuaW5zdHJ1Y3R1cmUuY29tMTAwMDAwMDAwMDAwMDEyOjRkZGUwNWU4Y2ExOTczYmNjYTliZmZjMTNlMTU0ODgyMGVlZTkzYTM%3D': '834fcf14-2921-494e-965b-8238c03ee628',
lti-gateway    |   state5a1150ce5f04965850aa8195eb4a8a1856f10866124fe3847d: 'https://canvas.instructure.com'
lti-gateway    | }
lti-gateway    | 2022-02-24T11:59:53.814Z provider:main Received idtoken for validation
lti-gateway    | 2022-02-24T11:59:53.814Z provider:auth Response state: 5a1150ce5f04965850aa8195eb4a8a1856f10866124fe3847d
lti-gateway    | 2022-02-24T11:59:53.814Z provider:auth Attempting to validate iss claim
lti-gateway    | 2022-02-24T11:59:53.814Z provider:auth Request Iss claim: https://canvas.instructure.com
lti-gateway    | 2022-02-24T11:59:53.814Z provider:auth Response Iss claim: https://canvas.instructure.com
lti-gateway    | 2022-02-24T11:59:53.814Z provider:auth Attempting to retrieve registered platform
lti-gateway    | Mongoose: platforms.find({ platformUrl: 'https://canvas.instructure.com', clientId: '10000000000001'}, { projection: { __v: 0, _id: 0 } })
lti-gateway    | Mongoose: platformstatuses.find({ id: 'b800e4b2812a7802ca41d10356cfc08b' }, { projection: { __v: 0, _id: 0 } })
lti-gateway    | 2022-02-24T11:59:53.818Z provider:auth Retrieving key from jwk_set
lti-gateway    | 2022-02-24T11:59:56.843Z provider:main Deleting state cookie and Database entry
lti-gateway    | Mongoose: states.find({ state: '5a1150ce5f04965850aa8195eb4a8a1856f10866124fe3847d' }, { projection: { __v: 0, _id: 0 } })
lti-gateway    | 2022-02-24T11:59:56.846Z provider:auth RequestError: connect ECONNREFUSED 127.0.0.1:80
lti-gateway    |     at ClientRequest.<anonymous> (/usr/src/app/node_modules/got/dist/source/core/index.js:962:111)
lti-gateway    |     at Object.onceWrapper (events.js:520:26)
lti-gateway    |     at ClientRequest.emit (events.js:412:35)
lti-gateway    |     at ClientRequest.origin.emit (/usr/src/app/node_modules/@szmarczak/http-timer/dist/source/index.js:43:20)
lti-gateway    |     at Socket.socketErrorListener (_http_client.js:475:9)
lti-gateway    |     at Socket.emit (events.js:400:28)
lti-gateway    |     at emitErrorNT (internal/streams/destroy.js:106:8)
lti-gateway    |     at emitErrorCloseNT (internal/streams/destroy.js:74:3)
lti-gateway    |     at processTicksAndRejections (internal/process/task_queues.js:82:21)
lti-gateway    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16)
lti-gateway    | 2022-02-24T11:59:56.846Z provider:main Passing request to invalid token handler

Screenshots See the network requests below: image

Ltijs version "ltijs": "^5.6.5"

NodeJS version v14.19.0

Platform used Canvas

Additional context Add any other context about the problem here.

Cvmcosta commented 2 years ago

Hello, the issue is most likely the ID Token validation, during this process Ltijs tries to retrieve the JWK Set from the LMS.

If you are using docker and testing against a local LMS, Ltijs will try to reach http://127.0.0.1/keys (example local LMS keyset URL) from inside the container, and it will fail since Ltijs and the LMS don't share the same local network.

Maxvanhattum commented 2 years ago

Thanks for you quick reply! I am indeed running the canvas instance locally. I am curious as to why it tries to find the keyset on that url. Is this not the one specified at the registerplatform method: authConfig: { method: 'JWK_SET', key: 'http://canvas.docker/api/lti/security/jwks' } ? If not, where can I configure this?

Cvmcosta commented 2 years ago

Interesting, yes, you are setting it correctly. Maybe it's mapping inside of the container? It would be helpful if you could access bash inside of the container and curl this URL from there, if it doesn't work we know that is the issue.

Maxvanhattum commented 2 years ago

Ah right, thanks for pointing me in the right way. I was confused because of the way the development/test instance of canvas is set up. The 'canvas.docker' domain name is in that setup configured to resolve to localhost on the host machine. So docker does first reach out to the URL through the host machine, but gets told that the domain name resolves to 127.0.0.1, which it then tries to follow in the docker container. For the slight change anyone else encounters the same problem when developing locally with canvas: simply configuring the docker container to use the host network 'solves' the issue.