What key must we validate lti_message_hint (the encoded JWT) against?

mismailzai
Community Novice

Hi all, we're working on an LTI 1.3 integration and have successfully implement the OAuth2 validation steps.

We're at the point now that we have a link displayed in our course, and when the link is clicked, Canvas displays our LTI application in an IFRAME and runs the user through an OAuth2 workflow. Once we've validate the user in this manner, we can also successfully validate our application and receive an application token. Thus, we know who the user is and we can successfully query Canvas on their behalf using our application token.

Our application is receiving a payload from Canvas that includes an iss, login_hint, client_id, target_link_uri, and lti_message_hint (the signed JWT). It's this final step that we're having trouble with. We understand that we must validate the JWT to ensure the message has not been tampered with and is indeed coming from Canvas. Can someone clarify what key this JWT needs to be validated against? We've tried the Canvas public keys with no luck.

Sample code in any programming language would be greatly appreciated.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Edited on June 15 at 12:39 PM to add more details:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

For example, here is a sample $_POST response (client_id and target_link_uri scrubbed):

array(6) {
["iss"]=>
string(30) "https://canvas.instructure.com"
["login_hint"]=>
string(40) "e20984648b488fb11b323741425126dca07aa300"
["client_id"]=>
string(17) "00000000000000000"
["target_link_uri"]=>
string(86) "https://OurLtiApplication/someEndpoint"
["lti_message_hint"]=>
string(423) "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJpZmllciI6IjhhOGFjNDQ0NDJjNjkxMDFjYjRiMzVkZjQyNTA5NzhhNjUyYzhmNTY0YWU3MDhjOTcxMGE1OTQ2ODAzMTY3MzUyMjA3YTczNjQ2YjRlOTA1NTYyNzM1MDMxNDM1ZGY1MzU3MDQ5Y2Q1YzMyNWYwMDA5N2Y0YjQ4YTA5MWQwMTA5IiwiY2FudmFzX2RvbWFpbiI6ImNhbnZhcy5zdGdlb3JnZXMuYmMuY2EiLCJjb250ZXh0X3R5cGUiOiJDb3Vyc2UiLCJjb250ZXh0X2lkIjo0OTcwMDAwMDAwMDAwMDg2MSwiZXhwIjoxNTkyMjQ5NzY4fQ.KmI75uFTAZBWe9F1mZ6nXnpabWVKDUm4HS6HjP-jExw"
["canvas_region"]=>
string(9) "us-east-1"
}

When we decode the lti_message_hint above, we get the following header:

{
"typ": "JWT",
"alg": "HS256"
}

and the following payload

{
"verifier": "8a8ac44442c69101cb4b35df4250978a652c8f564ae708c9710a5946803167352207a73646b4e905562735031435df5357049cd5c325f00097f4b48a091d0109",
"canvas_domain": "canvas.stgeorges.bc.ca",
"context_type": "Course",
"context_id": 49700000000000860,
"exp": 1592249768
}

So now we just need to validate the signature on the lti_message_hint -- which according to the OAuth2 spec (Validate JSON Web Tokens ) should be done using our client_secret. When we attempt to do so, the signature does not match.

Labels (1)