To Our Amazing Educators Everywhere,
Happy Teacher Appreciation Week!
Found this content helpful? Log in or sign up to leave a like!
I am working on building an assignment selection placement deep linking item for Canvas and am running into an issue where when I submit the deep linking message back to Canvas from the external tool iframe, I get the following error (see screenshot):
NoMethodError in Lti::IMS::DeepLinkingController#deep_linking_response
undefined method `count' for nil:NilClass
This posted message is being sent to the `deep_link_return_url` as defined in the deep linking request message. The data being sent includes a `data` value (automatically included in the url query params), `course_id` (also in url query params), and the `jwt` which is a JWT token of my payload signed with my private JWK (generated RSA 2048).
I've removed any private information from the payload so I could also share the JWT:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjIwMjMtMTEtMzBUMTk6NTg6MTVaIn0.eyJleHAiOjE3MDE0NjY3NjIsImlhdCI6MTcwMTM4MDM2MiwiaXNzIjoiaHR0cHM6Ly9jYW52YXMuaW5zdHJ1Y3R1cmUuY29tIiwiYXVkIjoiMTAwMDAwMDAwMDAwMTciLCJub25jZSI6InlpTk5MbHBaa2xOWVZVdW5SSkFQWlVOelp1bnh0aCIsImF6cCI6IjEwMDAwMDAwMDAwMDE3IiwiaHR0cHM6Ly9wdXJsLmltc2dsb2JhbC5vcmcvc3BlYy9sdGkvY2xhaW0vZGVwbG95bWVudF9pZCI6IjEwOjRkZGUwNWU4Y2ExOTczYmNjYTliZmZjMTNlMTU0ODgyMGVlZTkzYTMiLCJodHRwczovL3B1cmwuaW1zZ2xvYmFsLm9yZy9zcGVjL2x0aS9jbGFpbS9tZXNzYWdlX3R5cGUiOiJMdGlEZWVwTGlua2luZ1Jlc3BvbnNlIiwiaHR0cHM6Ly9wdXJsLmltc2dsb2JhbC5vcmcvc3BlYy9sdGkvY2xhaW0vdmVyc2lvbiI6IjEuMy4wIiwiaHR0cHM6Ly9wdXJsLmltc2dsb2JhbC5vcmcvc3BlYy9sdGktZGwvY2xhaW0vY29udGVudF9pdGVtcyI6W3sidHlwZSI6Imx0aVJlc291cmNlTGluayIsInRpdGxlIjoiU29tZSBUaXRsZSIsInRleHQiOiJEZXNjcmlwdGlvbiBvZiByZXNvdXJjZSBsaW5rLiIsInVybCI6Imh0dHBzOi8vbXkud2Vic2l0ZS5hcHAvbHRpL2F1dGgiLCJsaW5lSXRlbSI6eyJzY29yZU1heGltdW0iOjEwLCJsYWJlbCI6IkxhYmVsIiwicmVzb3VyY2VJZCI6InJlc291Y2UxIn0sImN1c3RvbSI6eyJzaXNfY291cnNlX2lkIjoiJENhbnZhcy5jb3Vyc2Uuc2lzU291cmNlSWQiLCJjb3Vyc2VfaWQiOiIkQ2FudmFzLmNvdXJzZS5pZCIsImFzc2lnbm1lbnRfaWQiOiIkQ2FudmFzLmFzc2lnbm1lbnQuaWQifSwid2luZG93Ijp7InRhcmdldE5hbWUiOiJfcGFyZW50In19XX0.BS0BND_kNBbSiotrXPHiqUfrppcpuiilYWorg0Lfet2xd6vDk4oZB_8GEE-cLLT6BWoCfvUjQLSIjUTM8H6xCm-GQj0akFv-EkI4Af_A3cJ68wl5O2id7fNo-lnOLZ60bg28s1xsrACzeWFAMNKghahHCwOaXdb_qLz2ZCyordcddYVjILyj7HmcBKNvoeq2V-sTitmyH-u60Pwi33AlDmqMvnUR9Gz869hNaA-R2GNZrm6ColDw4VXKaI-6oINf_7VIXzgcu5Q4lgLnd_L8jG7o43Tw6dZgpCbfQA8Cst-qMirqXrDe7yNWkf_FQDuwumCYrbseR_-uW0ROASgDnQ
JWK Public Key:
{"kty":"RSA","e":"AQAB","n":"teHSVfjYGapyYGhUuT-jY4u16DtXZ2kwovdTRrzEtWDJG4XIJok5UO9kL0j7rqnJak91gPTw-Hx8rvx4eADUUOwqA72iMbUbLDBJkvBBHPGl4HVS7dYQZ2N3EVS9axBVevLtcFrLpIoekLB6zzhLZvlZqIB3LZsKWprdPhsFujB-Rd2UNECPLAKktYTVlfA44kZg70NhddLN2yBjeomp9IcKx2g-1YyToSpfhn0EjPFWAImH27LOCeI21M4QmziAsbpO9KcBZRQxGijAJunBsLK0_Z0OFhHK8E4mZlm28aVj5uqPcTlFD5TSyu2JniNwPGSSB4B5sORLTPuzbw3onQ","kid":"2023-11-30T19:58:15Z"}
If you plug those into https://jwt.io/#debugger-io you can see that the token verifies and there is an iss value.
Does anyone know what this error message is referring to?
Solved! Go to Solution.
omg I'm going to chuck my laptop out the window. The name of the field needs to be `JWT` not `jwt`. 😠
My only suggestion would be to send the "aud" claim as an array. The Security Framework 1.1 spec is inconsistent on this matter: at one point it states that the claim MUST be an array (section 4.1.1), whilst at another it states that using an array is RECOMMENDED (section 5.1.2). So it would be worth trying this I think. Perhaps the "count" error is from trying to count the elements in the array but you are just passing a string?
Thanks for the suggestion! Unfortunately, that didn't fix it. I'll keep reading the security framework docs and see if I see anything else I can try.
On further review, it looks like your response may have the iss and aud claims the wrong way round; try switching them.
Hmm I agree that it looks swapped. I'm getting those from the original payload sent by the deep linking request message which looks like this:
{
https://purl.imsglobal.org/spec/lti/claim/message_type: 'LtiDeepLinkingRequest', https://purl.imsglobal.org/spec/lti/claim/version: '1.3.0', https://purl.imsglobal.org/spec/lti-dl/claim/deep_linking_settings: {…}, aud: '10000000000018', azp: '10000000000018', …}
aud: '10000000000018'
azp: '10000000000018'
email: 'email@email.com'
errors: {errors: {…}}
exp: 1701448115
family_name: 'Name'
given_name: 'Full'
https://purl.imsglobal.org/spec/lti-dl/claim/deep_linking_settings: {deep_link_return_url: 'http://canvas.docker/courses/1/deep_li…-BMjJvBBgj2pAvWNExmkM5GdM2ueW99GeHvfY', accept_types: Array(1), accept_presentation_document_targets: Array(2), accept_media_types: 'application/vnd.ims.lti.v1.ltilink', auto_create: false, …}
https://purl.imsglobal.org/spec/lti/claim/context: {id: '4dde05e8ca1973bcca9bffc13e1548820eee93a3', label: 'p101', title: 'Pockets 101', type: Array(1), validation_context: null, …}
https://purl.imsglobal.org/spec/lti/claim/custom: {canvas_org_guid: 'bnrTQIfbwTPspQovOOAw0c5Z9B8cJaAbih0p9EWo:canvas-lms', course_id: 1, assignment_id: '$Canvas.assignment.id', sis_course_id: 'sis_p101'}
https://purl.imsglobal.org/spec/lti/claim/deployment_id: '11:4dde05e8ca1973bcca9bffc13e1548820eee93a3'
https://purl.imsglobal.org/spec/lti/claim/launch_presentation: {document_target: 'iframe', return_url: 'http://canvas.docker/courses/1/external_content/success/external_tool_dialog', locale: 'en', height: 400, width: 800, …}
https://purl.imsglobal.org/spec/lti/claim/lis: {person_sourcedid: null, course_offering_sourcedid: 'sis_p101', validation_context: null, errors: {…}}
https://purl.imsglobal.org/spec/lti/claim/lti11_legacy_user_id: '535fa085f22b4655f48cd5a36a9215f64c062838'
https://purl.imsglobal.org/spec/lti/claim/lti1p1: {user_id: '535fa085f22b4655f48cd5a36a9215f64c062838', validation_context: null, errors: {…}}
https://purl.imsglobal.org/spec/lti/claim/message_type: 'LtiDeepLinkingRequest'
https://purl.imsglobal.org/spec/lti/claim/roles: (3) ['http://purl.imsglobal.org/vocab/lis/v2/institution/person#Administrator', 'http://purl.imsglobal.org/vocab/lis/v2/system/person#SysAdmin', 'http://purl.imsglobal.org/vocab/lis/v2/system/person#User']
https://purl.imsglobal.org/spec/lti/claim/target_link_uri: 'https://b894-136-41-224-92.ngrok-free.app/lti/assignment_selection'
https://purl.imsglobal.org/spec/lti/claim/tool_platform: {guid: 'bnrTQIfbwTPspQovOOAw0c5Z9B8cJaAbih0p9EWo:canvas-lms', name: 'Pocket Prep', version: 'cloud', product_family_code: 'canvas', validation_context: null, …}
https://purl.imsglobal.org/spec/lti/claim/version: '1.3.0'
https://www.instructure.com/placement: 'assignment_selection'
iat: 1701444515
iss: 'https://canvas.instructure.com'
locale: 'en'
name: 'Full Name'
nonce: 'xYjOQaul3gM2rlAdrEsTZQ6MeTwKZe'
picture: 'http://canvas.instructure.com/images/messages/avatar-50.png'
sub: '218cda6a-da4d-4b74-8ab9-87e3322c52ca'
}
But I did go ahead and swap the iss and aud and it didn't make any difference 😢
I don't know if it's a red herring, but the `count` error is coming from this line:
https://github.com/nov/json-jwt/blob/master/lib/json/jwt.rb#L108
Which makes me wonder if there's something wrong with the `jwt` itself.
Interesting; so it looks like it is a Ruby issue rather than an LTI one. Ruby does not seem to recognise jwt_string as being a string on which it can apply the count method. Sorry, I'm not a Ruby expert so probably can't help you with this.
Well Ruby seems to think that `jwt_string` is nil which makes me think that it isn't necessarily a Ruby issue but an issue with what Canvas is trying to send for the `jwt_string`. For some reason, Canvas isn't passing a value for that variable. Does it seem like I'm doing this form correctly to post the response message?
<form method="post" action="http://canvas.docker/courses/1/deep_linking_response?data=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJub25jZSI6Ijg5MjJiNmIwLTkwODEtNDZlZS04YWI3LTlhZTNlYjAyMTBiYyIsIm1vZGFsIjp0cnVlLCJwbGFjZW1lbnQiOiJhc3NpZ25tZW50X3NlbGVjdGlvbiJ9._CaAfQ6B6RIynZFJa5r_VzmrRWLaLcYgXsyc8xT4fmU">
<input type="hidden" value="eyJhbGciOiJSUzI1NiIsImtpZCI6IjIwMjMtMTEtMzBUMTk6NTg6MTVaIn0.eyJleHAiOjE3MDE1MzIwMjEsImlhdCI6MTcwMTQ0NTYyMSwiaXNzIjoiaHR0cDovL2NhbnZhcy5kb2NrZXIiLCJhdWQiOiJodHRwOi8vY2FudmFzLmRvY2tlciIsInN1YiI6IjEwMDAwMDAwMDAwMDE4Iiwibm9uY2UiOiJJdlZuYWdkOTd5cm11R2lnR1oyalg5MGdZaW8ydGMiLCJhenAiOiIxMDAwMDAwMDAwMDAxOCIsImp0aSI6IjIxOGNkYTZhLWRhNGQtNGI3NC04YWI5LTg3ZTMzMjJjNTJjYSIsImh0dHBzOi8vcHVybC5pbXNnbG9iYWwub3JnL3NwZWMvbHRpL2NsYWltL2RlcGxveW1lbnRfaWQiOiIxMTo0ZGRlMDVlOGNhMTk3M2JjY2E5YmZmYzEzZTE1NDg4MjBlZWU5M2EzIiwiaHR0cHM6Ly9wdXJsLmltc2dsb2JhbC5vcmcvc3BlYy9sdGkvY2xhaW0vbWVzc2FnZV90eXBlIjoiTHRpRGVlcExpbmtpbmdSZXNwb25zZSIsImh0dHBzOi8vcHVybC5pbXNnbG9iYWwub3JnL3NwZWMvbHRpL2NsYWltL3ZlcnNpb24iOiIxLjMuMCIsImh0dHBzOi8vcHVybC5pbXNnbG9iYWwub3JnL3NwZWMvbHRpLWRsL2NsYWltL2NvbnRlbnRfaXRlbXMiOlt7InR5cGUiOiJsdGlSZXNvdXJjZUxpbmsiLCJ0aXRsZSI6IlNvbWUgVGl0bGUiLCJ0ZXh0IjoiRGVzY3JpcHRpb24gb2YgcmVzb3VyY2UgbGluay4iLCJ1cmwiOiJodHRwczovL215LndlYnNpdGUuYXBwL2x0aS9hdXRoIiwibGluZUl0ZW0iOnsic2NvcmVNYXhpbXVtIjoxMCwibGFiZWwiOiJMYWJlbCIsInJlc291cmNlSWQiOiJyZXNvdWNlMSJ9LCJjdXN0b20iOnsic2lzX2NvdXJzZV9pZCI6IiRDYW52YXMuY291cnNlLnNpc1NvdXJjZUlkIiwiY291cnNlX2lkIjoiJENhbnZhcy5jb3Vyc2UuaWQiLCJhc3NpZ25tZW50X2lkIjoiJENhbnZhcy5hc3NpZ25tZW50LmlkIn0sIndpbmRvdyI6eyJ0YXJnZXROYW1lIjoiX3BhcmVudCJ9fV19.LPULsRU79_-pgCLUNRA15pUQFWETnEz8B-aYTcBcLBPT8APbVmYzpL0q9Q-3m5xm9AMrxLJtnVzKlvlOvaVqwliqHqUm9OPc5A4OkUX1exU3zD7lYOZGpe6lG5AgvWHAN3mj8a5TDKhlLE8WamsSfjjqY8H1GwJsupNqPeerjC6cAWmDdwwWt4yyk3bXHWywCkJmfZ0yP6ttsfwrhTBfAdmjD6P964jSVX-_5EpGDcoX6X48xKj2qzn3sw7-NqnZHQ7lzwq_myuehuAq-NTYCrvXc9Q_R80ZrBoY04PaSdH_rYcWFXCjio6fn0Nu10llJQpBxzFG1daBX693L0Lriw" name="jwt">
<input type="submit" value="Submit">
</form>
omg I'm going to chuck my laptop out the window. The name of the field needs to be `JWT` not `jwt`. 😠
Yes, that looks like the cause.
Well I appreciate you sticking with me through that debugging! Have a good day!
To participate in the Instructure Community, you need to sign up or log in:
Sign In