instructure / ims-lti

A Ruby library to help implement IMS LTI tool consumers and providers
MIT License
199 stars 122 forks source link

OAuth Still Failing with gem version 2.2.1 #144

Closed itsalljustaride closed 6 years ago

itsalljustaride commented 6 years ago

Thanks for you help with getting me on the 2.0 version of the gem. My LTI tool provider launches are still failing though on 2.2.1, and this time they don't clear even with a reload of page, so in some ways it's a step back, but I have a feeling something else is going on. I'm creating an authenticator thusly:

authenticator = IMS::LTI::Services::MessageAuthenticator.new(@request.url, @params, secret) authenticator.valid_signature?

That still returns false.

Here is a dump of the console output for the request, params, and validator that may help, hopefully:

`App 9783 stdout: --- OAUTH Key ====> ocill-lti-key App 9783 stdout: --- OAUTH Secret ====> REDACTED! App 9783 stdout: --- REQUEST URL https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create App 9783 stdout: --- REQUEST PARAMS {"oauth_consumer_key"=>"ocill-lti-key", "oauth_signature_method"=>"HMAC-SHA1", "oauth_timestamp"=>"1510067228", "oauth_nonce"=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", "oauth_version"=>"1.0", "context_id"=>"de25c863939f3cacfc02480738d072d95597842c", "context_label"=>"johnathb Sandbox", "context_title"=>"A Canvas training course for johnathb", "custom_canvas_assignment_points_possible"=>"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active", "ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", "launch_presentation_document_target"=>"iframe", "launch_presentation_locale"=>"en", "launch_presentation_return_url"=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", "lis_outcome_service_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", "lti_message_type"=>"basic-lti-launch-request", "lti_version"=>"LTI-1p0", "oauth_callback"=>"about:blank", "resource_link_id"=>"52e0499f9ed929340aec886dd08c7035e45471f5", "resource_link_title"=>"OCILL Staging Test", "roles"=>"Instructor", "tool_consumer_info_product_family_code"=>"canvas", "tool_consumer_info_version"=>"cloud", "tool_consumer_instance_contact_email"=>"notifications@instructure.com", "tool_consumer_instance_guid"=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", "tool_consumer_instance_name"=>"University of Michigan - Ann Arbor", "user_id"=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", "oauth_signature"=>"7jq4lBIBYoMzIeShPZbPNJjOrEs=", "controller"=>"launch", "action"=>"create"}

App 9783 stdout: --- AUTHENTICATOR INSPECT ===> #<IMS::LTI::Services::MessageAuthenticator:0x007fd77b5535c0 @launch_url="https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create", @params={"oauth_consumer_key"=>"ocill-lti-key", "oauth_signature_method"=>"HMAC-SHA1", "oauth_timestamp"=>"1510067228", "oauth_nonce"=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", "oauth_version"=>"1.0", "context_id"=>"de25c863939f3cacfc02480738d072d95597842c", "context_label"=>"johnathb Sandbox", "context_title"=>"A Canvas training course for johnathb", "custom_canvas_assignment_points_possible"=>"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active", "ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", "launch_presentation_document_target"=>"iframe", "launch_presentation_locale"=>"en", "launch_presentation_return_url"=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", "lis_outcome_service_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", "lti_message_type"=>"basic-lti-launch-request", "lti_version"=>"LTI-1p0", "oauth_callback"=>"about:blank", "resource_link_id"=>"52e0499f9ed929340aec886dd08c7035e45471f5", "resource_link_title"=>"OCILL Staging Test", "roles"=>"Instructor", "tool_consumer_info_product_family_code"=>"canvas", "tool_consumer_info_version"=>"cloud", "tool_consumer_instance_contact_email"=>"notifications@instructure.com", "tool_consumer_instance_guid"=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", "tool_consumer_instance_name"=>"University of Michigan - Ann Arbor", "user_id"=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", "oauth_signature"=>"7jq4lBIBYoMzIeShPZbPNJjOrEs=", "controller"=>"launch", "action"=>"create"}, @options={:consumer_key=>"ocill-lti-key", :signature_method=>"HMAC-SHA1", :timestamp=>"1510067228", :nonce=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", :version=>"1.0", :callback=>"about:blank"}, @parsed_params={:context_id=>"de25c863939f3cacfc02480738d072d95597842c", :context_label=>"johnathb Sandbox", :context_title=>"A Canvas training course for johnathb", :custom_canvas_assignment_points_possible=>"10", :custom_canvas_assignment_title=>"OCILL Staging Test", :custom_canvas_enrollment_state=>"active", :ext_ims_lis_basic_outcome_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", :ext_lti_assignment_id=>"f9139721-be1f-473a-91b5-6a08a386074c", :ext_outcome_data_values_accepted=>"url,text", :ext_outcome_result_total_score_accepted=>"true", :ext_outcomes_tool_placement_url=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", :ext_roles=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", :launch_presentation_document_target=>"iframe", :launch_presentation_locale=>"en", :launch_presentation_return_url=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", :lis_outcome_service_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", :lti_message_type=>"basic-lti-launch-request", :lti_version=>"LTI-1p0", :resource_link_id=>"52e0499f9ed929340aec886dd08c7035e45471f5", :resource_link_title=>"OCILL Staging Test", :roles=>"Instructor", :tool_consumer_info_product_family_code=>"canvas", :tool_consumer_info_version=>"cloud", :tool_consumer_instance_contact_email=>"notifications@instructure.com", :tool_consumer_instance_guid=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", :tool_consumer_instance_name=>"University of Michigan - Ann Arbor", :user_id=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", :controller=>"launch", :action=>"create"}, @consumer_key="ocill-lti-key", @signature="7jq4lBIBYoMzIeShPZbPNJjOrEs=", @secret="REDACTED!", @message=#<IMS::LTI::Models::Messages::BasicLTILaunchRequest:0x007fd7836bb6d0 @custom_params={"custom_canvas_assignment_points_possible"=>"10", "custom_canvas_assignment_title"=>"OCILL Staging Test", "custom_canvas_enrollment_state"=>"active"}, @ext_params={"ext_ims_lis_basic_outcome_url"=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", "ext_lti_assignment_id"=>"f9139721-be1f-473a-91b5-6a08a386074c", "ext_outcome_data_values_accepted"=>"url,text", "ext_outcome_result_total_score_accepted"=>"true", "ext_outcomes_tool_placement_url"=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", "ext_roles"=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User"}, @unknown_params={"controller"=>"launch", "action"=>"create"}, @oauth_consumer_key="ocill-lti-key", @oauth_signature_method="HMAC-SHA1", @oauth_timestamp="1510067228", @oauth_nonce="70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", @oauth_version="1.0", @context_id="de25c863939f3cacfc02480738d072d95597842c", @context_label="johnathb Sandbox", @context_title="A Canvas training course for johnathb", @launch_presentation_document_target="iframe", @launch_presentation_locale="en", @launch_presentation_return_url="https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", @lis_outcome_service_url="https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", @lti_message_type="basic-lti-launch-request", @lti_version="LTI-1p0", @oauth_callback="about:blank", @resource_link_id="52e0499f9ed929340aec886dd08c7035e45471f5", @resource_link_title="OCILL Staging Test", @roles="Instructor", @tool_consumer_info_product_family_code="canvas", @tool_consumer_info_version="cloud", @tool_consumer_instance_contact_email="notifications@instructure.com", @tool_consumer_instance_guid="7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", @tool_consumer_instance_name="University of Michigan - Ann Arbor", @user_id="1ec00186b63b783a994fd2d5b7648ba6cdfe9807", @oauth_signature="7jq4lBIBYoMzIeShPZbPNJjOrEs=", @launch_url="https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create">, @simple_oauth_header=#<SimpleOAuth::Header:0x007fd7836bb108 @method="POST", @uri=#<URI::HTTPS https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create>, @params={:context_id=>"de25c863939f3cacfc02480738d072d95597842c", :context_label=>"johnathb Sandbox", :context_title=>"A Canvas training course for johnathb", :custom_canvas_assignment_points_possible=>"10", :custom_canvas_assignment_title=>"OCILL Staging Test", :custom_canvas_enrollment_state=>"active", :ext_ims_lis_basic_outcome_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/ext_grade_passback", :ext_lti_assignment_id=>"f9139721-be1f-473a-91b5-6a08a386074c", :ext_outcome_data_values_accepted=>"url,text", :ext_outcome_result_total_score_accepted=>"true", :ext_outcomes_tool_placement_url=>"https://umich.instructure.com/api/lti/v1/turnitin/outcomes_placement/10530", :ext_roles=>"urn:lti:instrole:ims/lis/Administrator,urn:lti:instrole:ims/lis/Instructor,urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Instructor,urn:lti:sysrole:ims/lis/User", :launch_presentation_document_target=>"iframe", :launch_presentation_locale=>"en", :launch_presentation_return_url=>"https://umich.instructure.com/courses/56125/external_content/success/external_tool_redirect", :lis_outcome_service_url=>"https://umich.instructure.com/api/lti/v1/tools/10530/grade_passback", :lti_message_type=>"basic-lti-launch-request", :lti_version=>"LTI-1p0", :resource_link_id=>"52e0499f9ed929340aec886dd08c7035e45471f5", :resource_link_title=>"OCILL Staging Test", :roles=>"Instructor", :tool_consumer_info_product_family_code=>"canvas", :tool_consumer_info_version=>"cloud", :tool_consumer_instance_contact_email=>"notifications@instructure.com", :tool_consumer_instance_guid=>"7db438071375c02373713c12c73869ff2f470b68.umich.instructure.com", :tool_consumer_instance_name=>"University of Michigan - Ann Arbor", :user_id=>"1ec00186b63b783a994fd2d5b7648ba6cdfe9807", :controller=>"launch", :action=>"create"}, @options={:nonce=>"70h3qDQemquvfZeKZ03OIJt5Me06hmoUuA4DEscIgQ", :signature_method=>"HMAC-SHA1", :timestamp=>"1510067228", :version=>"1.0", :consumer_key=>"ocill-lti-key", :callback=>"about:blank", :consumer_secret=>"REDACTED!"}>> `

rivernate commented 6 years ago

What is the url that you are launching to?

There is also this tool: https://lti-tool-provider.herokuapp.com/ that has a signature test functionality you can try and use to troubleshoot the signature generation.

itsalljustaride commented 6 years ago

I am trying to launch to https://lrc-tesuto.lrc.lsa.umich.edu/ocill/launch/create

I tried the heroku app you suggested, and it works on its own as an LTI tool, but the signature test proxy is still failing when I test it with my app's url/key/secret. I can generate the signature, but when I submit it it still returns false when I try the valid_signature? check.

You can attempt yourself with key:test and secret:secret if you like. Thanks for your help.

itsalljustaride commented 6 years ago

I'm also getting the following lines showing up in console if that helps:

App 12389 stderr: Unknown parameter selection_directive App 12389 stderr: Unknown parameter controller App 12389 stderr: Unknown parameter action

rivernate commented 6 years ago

It looks like the issue is that you are using the params method, in rails this will add additional keys, i.e. controller, and action. I would suggest using request.query_parameters.merge(request.request_parameters) instead. That will give you just the parameters that were sent as part of the request.

If that doesn't fix the problem, then I would look at the signature test proxy again. It will show you the base string used for generating the signature. You then would need to compare it to the base string generated by your code and see where the difference is.

itsalljustaride commented 6 years ago

Great! That looks like it cured the problem. Thanks so much!

itsalljustaride commented 6 years ago

So, apparently this only fixed the persistent failure of the oauth verification. It still fails on the first launch, and is successful thereafter, putting me back at square-one from the behavior I was seeing with the 1.0 version of the gem.

This most likely has something to do with my request flow or something, but I don't really know where to start debugging. To compound matters, since the 2.0 version of the gem also does not include support for outcomes, it is a bit of a non-starter for me even if I could get the oauth verification working.

rivernate commented 6 years ago

I would try and duplicate it using the signature test proxy, When a signature doesn't match the best thing you can do is compare your base strings and find out what id different between yours and the one used to sign the launch. The test tool will make available the one that it uses to generate the signature.

itsalljustaride commented 6 years ago

Thanks, that helped. It looks like what was happening is that the controller flow had a test in it to see if cookies were enabled that was redirecting it, turning the POST request into a GET request, which was failing verification.