Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth signature from Moodle 2.9 does not match signature built from pylti #52

Closed
sayeghr opened this issue Aug 24, 2015 · 6 comments
Closed

Comments

@sayeghr
Copy link

sayeghr commented Aug 24, 2015

Hi there,

Not sure if I am doing something wrong but I have set up a moodle instance on my local machine to use the consumer key: __consumer_key__ and secret key: __lti_secret__ with the mit_lti_flask_sample app and I am finding that hitting the / endpoint causes a pylti.flask - verify_request failed error.

I used some breakpoints and I found that the oauth signature that moodle is sending does not match the signature that is being built by pylti. Do you have any insight as to what might be going on here?

@pwilkins
Copy link
Contributor

@sayeghr Please paste the complete contents of your terminal console for the error you describe. (You can alternately create a gist of the output and share a link to the gist).

@carsongee
Copy link
Contributor

TL;DR: It probably is a missing slash in your tool URL.

It turns out between Flask and Moodle there is some finickiness about using the right URLs. After a fair amount of time debugging with @pwilkins I finally got things instrumented enough to find out at least what our issue is with a bit of luck. It turns out that if you leave out a trailing / on your `Tool base URL:
image
Moodle will sign the URL without the /, but when we get the URL for pylti in the flask example the slash has been added back in(I believe this is a feature of Flask). This causes pyLTI to sign the wrong URL which causes an incorrect authentication signature.

The settings in the screenshot were tested to work with the default flask sample app and Moodle 2.9.

@sayeghr
Copy link
Author

sayeghr commented Aug 26, 2015

Thank you very much for the thorough reply. I can confirm that adding the / in moodle made the difference and I am now able to get further along. However, I am now coming across a different issue. PyLTI now seems to fail with an LTIRoleException('Not authorized.') but the endpoint has only the @LTI(request='initial', error=error, app=app). See the console below:

werkzeug - * Running on http://localhost:5000/
werkzeug - * Restarting with reloader
pylti.flask - verify request=initial
pylti.flask - {'lti_version': u'LTI-1p0', 'lis_result_sourcedid': u'{"data":{"instanceid":"2","userid":"2","typeid":"2","launchid":315235773},"hash":"f9f476fa569f7ac34a3ea4c0c1c5e23133a02f018cc10b2f2d0ab358538bbc18"}', 'resource_link_description': u'', 'tool_consumer_info_version': u'2015051101.02', 'tool_consumer_instance_guid': u'localhost', 'oauth_signature': u'Gn+vuhHeYWoVwhnj01iBTOz0BLE=', 'context_label': u'LTI test', 'lti_message_type': u'basic-lti-launch-request', 'ext_user_username': u'admin', 'lis_person_name_full': u'- Admin -', 'context_title': u'LTI Test', 'user_id': u'2', 'oauth_consumer_key': u'consumer_key', 'launch_presentation_locale': u'en', 'context_id': u'4', 'lis_outcome_service_url': u'http://localhost:8888/moodle29/mod/lti/service.php', 'tool_consumer_info_product_family_code': u'moodle', 'oauth_callback': u'about:blank', 'lis_person_name_family': u'-', 'oauth_nonce': u'7dd9d73ea2f48ca0441da355b464da41', 'oauth_timestamp': u'1440613509', 'resource_link_title': u'LTI Second Test', 'oauth_signature_method': u'HMAC-SHA1', 'oauth_version': u'1.0', 'lis_course_section_sourcedid': u'', 'lis_person_sourcedid': u'', 'tool_consumer_instance_name': u'Moodle 2.9', 'resource_link_id': u'2', 'lis_person_contact_email_primary': u'admin@localhost', 'roles': u'Instructor,urn:lti:sysrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Administrator', 'context_type': u'CourseSection', 'ext_lms': u'moodle-2', 'lis_person_name_given': u'- Admin', 'launch_presentation_return_url': u'http://localhost:8888/moodle29/mod/lti/return.php?course=4&launch_container=3&instanceid=2&sesskey=eCECu2TrUe', 'launch_presentation_document_target': u'iframe'}
pylti.flask - verify_request?
pylti.common - consumers {'consumer_key': {'secret': 'lti_secret', 'cert': '/Users/enabletc/Projects/mit_lti_flask_sample/consumer_key.pem'}}
pylti.common - url http://localhost:5000/
pylti.common - method POST
pylti.common - headers Cookie: ga=GA1.1.408113343.1428499996; __utma=1.408113343.1428499996.1428499996.1428499996.1; __utmz=1.1428499996.1.1.utmcsr=localhost:5000|utmccn=(referral)|utmcmd=referral|utmcct=/webplayer/T038_Test/T038_Test.unity3d; fldt_active=flDebugProfilerPanel; session=.eJyVU8uK2zAU_ZXgRVZJ_Y4fENoydDHQXdOdQcjSdS1GloweoWHIv_fKTjMNnS7qlXzOuVfnPvQaMa0c_HRE8KiNimh3ByTtQSL29fS8cWAdUpJ6xUYyG7CgHHVCK2LAeaOIN0E7Oje3cSw1o3LU1rU1fvGkNZeQNXjgsXQiXmM-zOP8kWlvLByL7S13uJ0KBeaYb4WyjioGgh-zrQVrX-ByhKcvTz47me8QDAlLtHdMT0AsmLNg8H9ObkHByi3dDMZiWYsP5ghMVEisWEzUXDAv5ZNQn-5pH4MURR8DnYQM0v17pJfB3X7zOeTZvCf5Ic6g3jQ3BbbcS0cstosBX4b12kWcOtpFLZ7eeoX_XZR10a6LPJb3ALjL_KhYu75AaZ03VVZWdXpFYqR2XHQ9yw91VWbVYciLoqhYeWh6VlZQppDwukYoS5sKUl4WKaWcD3k1JANl_EDLrKy76BpKcIJQ70ZcG8GoA_TvjIeVOGP1uErrru3TOcEAHdRhCtZPYAhOHmnyABBy1ymNpaMg75O0r9OKlmk6NH1Cq2bIEmjKIuND2VAMwEYuPSRSqJd167O_YCechNvufwO8lG9O6xMwWoJF5hn7bTxz2uxwlVsso7UXG9hWTDbGkcXL-ATK6J-qMKh_y_CGMLTfvq6_AGCEPvM.CL-V7A.vZoFSxQ7vZGH9rg25h129uHulmo; SQLiteManager_currentLangue=2
Origin: http://localhost:8888
Content-Length: 1563
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Version/8.0.8 Safari/600.8.9
Connection: keep-alive
Referer: http://localhost:8888/moodle29/mod/lti/launch.php?id=14
Host: localhost:5000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,
/_;q=0.8
Accept-Language: en-us
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate

pylti.common - params {'lti_version': u'LTI-1p0', 'lis_result_sourcedid': u'{"data":{"instanceid":"2","userid":"2","typeid":"2","launchid":315235773},"hash":"f9f476fa569f7ac34a3ea4c0c1c5e23133a02f018cc10b2f2d0ab358538bbc18"}', 'resource_link_description': u'', 'tool_consumer_info_version': u'2015051101.02', 'tool_consumer_instance_guid': u'localhost', 'oauth_signature': u'Gn+vuhHeYWoVwhnj01iBTOz0BLE=', 'context_label': u'LTI test', 'lti_message_type': u'basic-lti-launch-request', 'ext_user_username': u'admin', 'lis_person_name_full': u'- Admin -', 'context_title': u'LTI Test', 'user_id': u'2', 'oauth_consumer_key': u'consumer_key', 'launch_presentation_locale': u'en', 'context_id': u'4', 'lis_outcome_service_url': u'http://localhost:8888/moodle29/mod/lti/service.php', 'tool_consumer_info_product_family_code': u'moodle', 'oauth_callback': u'about:blank', 'lis_person_name_family': u'-', 'oauth_nonce': u'7dd9d73ea2f48ca0441da355b464da41', 'oauth_timestamp': u'1440613509', 'resource_link_title': u'LTI Second Test', 'oauth_signature_method': u'HMAC-SHA1', 'oauth_version': u'1.0', 'lis_course_section_sourcedid': u'', 'lis_person_sourcedid': u'', 'tool_consumer_instance_name': u'Moodle 2.9', 'resource_link_id': u'2', 'lis_person_contact_email_primary': u'admin@localhost', 'roles': u'Instructor,urn:lti:sysrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Administrator', 'context_type': u'CourseSection', 'ext_lms': u'moodle-2', 'lis_person_name_given': u'- Admin', 'launch_presentation_return_url': u'http://localhost:8888/moodle29/mod/lti/return.php?course=4&launch_container=3&instanceid=2&sesskey=eCECu2TrUe', 'launch_presentation_document_target': u'iframe'}
pylti.flask - verify_request success
pylti.flask - params oauth_consumer_key=consumer_key
pylti.flask - params launch_presentation_return_url=http://localhost:8888/moodle29/mod/lti/return.php?course=4&launch_container=3&instanceid=2&sesskey=eCECu2TrUe
pylti.flask - params user_id=2
pylti.flask - params oauth_nonce=7dd9d73ea2f48ca0441da355b464da41
pylti.flask - params context_label=LTI test
pylti.flask - params context_id=4
pylti.flask - params resource_link_title=LTI Second Test
pylti.flask - params resource_link_id=2
pylti.flask - params lis_person_contact_email_primary=admin@localhost
pylti.flask - params lis_person_name_full=- Admin -
pylti.flask - params lis_person_name_family=-
pylti.flask - params lis_person_name_given=- Admin
pylti.flask - params lis_result_sourcedid={"data":{"instanceid":"2","userid":"2","typeid":"2","launchid":315235773},"hash":"f9f476fa569f7ac34a3ea4c0c1c5e23133a02f018cc10b2f2d0ab358538bbc18"}
pylti.flask - params lti_version=LTI-1p0
pylti.flask - params roles=Instructor,urn:lti:sysrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Administrator
pylti.flask - params lis_outcome_service_url=http://localhost:8888/moodle29/mod/lti/service.php
pylti.flask - check_role lti_role=Instructor,urn:lti:sysrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Administrator decorator_role=any
pylti.flask - is_role any
pylti.flask - is_role roles_list=[u'Administrator', u'Instructor', u'Student'] role=Instructor,urn:lti:sysrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Administrator in list=False
{'exception': LTIRoleException('Not authorized.',), 'args': (), 'kwargs': {}}
werkzeug - 127.0.0.1 - - [26/Aug/2015 14:25:09] "POST / HTTP/1.1" 200 -

@sayeghr
Copy link
Author

sayeghr commented Sep 3, 2015

The MIT LTI flask sample seems to work with Moodle now. I will now close the issue, thanks.

@sayeghr sayeghr closed this as completed Sep 3, 2015
@dirkcgrunwald
Copy link

I'd like to follow up on this since I've spent several hours debugging the same issue. I'm using Moodle 3.1 and connecting to the sample flask server.

I disabled debugging in the flask server, which also disables the automatic adding-on of the missing "/". When I do that, and omit the trailing "/" in the moodle LTI config, the LTI call fails as expected. When I add it, I get the same issue with the consumer_key as noted above.

I am able to use the sample tool provider at http://ltiapps.net/test/tp.php with no problems when Moodle is the tool consumer. Likewise, I can use the sample tool consumer at http://ltiapps.net/test/tc.php against the PyLTI tool provider with no problems.

But, I'm having no love at all getting Moodle to talk to the PyLTI tool provider out of the box. The only change I made was to remove the specific version requirement of uWSGI because that does not build on Ubuntu ( see https://github.com/dirkcgrunwald/mit_lti_flask_sample/blob/master/requirements.txt ). I'm going to try using Centos (in docker) as that appears to be the preferred build environment.

Also, in the current version, it appears that a file "consumer_key.pem" is written in the local directory when running the server -- is this intended?

@jordanell
Copy link

After 2 days of research on this, I finally find this post!

I am writing this because I am using Node, Express and a package called IMS-LTI (https://www.npmjs.com/package/ims-lti). It had the exact same issue with the trailing / and the same solution. Posting this in case some poor soul has the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants