Celebrate Excellence in Education: Nominate Outstanding Educators by April 15!
Found this content helpful? Log in or sign up to leave a like!
Hi,
I created an LTI application with .Net. I have tried different libraries to create OAuth 1.0 signature, but it never matches with the one comes from Canvas. I checked it with this tool: http://lti.tools/oauth/ and it matches with the OAuth signature I generated, however not with the "signature" parameter comes from Canvas.
URL: https://localhost:44397/default.aspx
Consumer Key: orhun-123
Shared Secret: orhun-123
Signature comes from Canvas: z2tzUWURgkf6m56L7wrUyqe50wE=
Currently, I am using this code to generate the OAuth signature:
Thank you,
Solved! Go to Solution.
What is your tool's URL, as entered in Canvas?
Above, have you listed all of the parameters you are receiving from Canvas? Are you using all of them?
Some of the compulsory oauth ones seem to be missing, eg., oauth_signature_method, oauth_version. And then there are all the other ones, eg, lti_version, context_id, lis_person_name_full, roles, ... ... ...
Hi Peter,
Thanks for the response. I just figured out the problem. There was a couple of things I was missing; the first thing; I didn't know that I should use all of the parameters(except oauth_signature) sent to the launch url to create the signature base. And the second thing was just an encoding issue.
What was the issue with encoding? Did you have to change something on your code/call? I am having a similar issue but it works with a development server, but not a production server. Trying to figure out if there is an encoding issue.
Hi Jonathan,
For me, the problem was creating the signature base
To create the Signature Base:
1- Get all of the parameters except "oauth signature" sent by Canvas with POST from the launch.
2- I made a loop for each parameter, and encode only Key and Values, they look like this: encodedKey=EncodedValue. I don't know which language you are using but, in c# it looks similar to this:
$"&{Uri.EscapeDataString(key)}={Uri.EscapeDataString(value)}
3- Sort them alphabetically with the Key names(&Key=Value)
4- Create a string from this list, and Encode this string one more time(the whole string).
5- Add the string you created to "POST&{Your Launch Url}&{The string you just created}"
After these, you will just create the signature with using this signature base which is the standard way. I hope this will help.
Your post was extremely helpful, but missing one crucial part: the way to generate the Key used in HMACSHA1 encoding is $"{Secret}&" where Secret is from the Key and Secret that you use to create the LTI tool in canvas. You don't have to put anything else there.
When I was researching this topic I somehow missed this and tried to put $"{Secret}&{Key}" in there, but the Key is unnecessary.
(Grain of Salt: This is using the .NET Core 3.0 library System.Security.Cryptography.)
Hey, I followed your all instruction steps, but the signatures are not getting matched.
The canvas provided signature and my signatures are totally different.
Can you please little bit elaborate with an example, hope it may help.
Thanks in Advance.
Were you able to generate the correct oauth_signature from your end?
In case it helps, you can check an OAuth signature using a tool like the one at http://lti.tools/oauth. Note also that, when your launch URL includes query parameters, Canvas does not generate a correct signature unless the oauth_compliant property has been set to true in the app configuration (see https://canvas.instructure.com/doc/api/file.tools_xml.html).
Greetings, I'm also having an issue with generating a matching oauth signature to interface with canvas. As I'm understanding it, we're getting the oauth_signature back from canvas as part of the POST request, and we should be able to regenerate that same oauth_signature using the process outlined in orhunk90's solution above.
I'm trying to implement this integration in javascript. Does anyone know of anything special I might be missing for a javascript implementation of this Oauth1.0 with LTI1.0 integration? Many thanks.
Canvas will only generate a signature which complies with the OAuth 1 spec if you set the tool's "oauth_compliant" property to "true". Without this, any URL which includes a query parameter will have an invalid signature. And even with this any query parameter which comprises just a name (no value or equals sign) will cause Canvas to generate an invalid signature.
HTH.
I think the only way to set this property is via the XML configuration of the tool - see https://unh.instructure.com/doc/api/file.tools_xml.html. I also believe there is no way of checking the current value of this property.
Yes, I would expect the signatures to match, unless your URL has a query parameter which comprises just a name (no value or equals sign).
Hmm, i've reached the point where the signature i'm generating is matching with what the external tool generates, but i'm still not managing to match my signature with the one canvas generates. I've got the oauth_compliant field set to true using the xml paste option when I add the external tool, and I've verified that I'm not sending any incomplete query parameters. Are you aware of any other gotchas that would lead to Canvas returning an invalid signature here? Thank you so much!
One thing I've hit in validating LTI OAuth 1.0 signatures before is when you have a proxy in-front of your application server that handles HTTPS termination and then forwards the request onto your application server over HTTP. Unless you configure your application server to pull through the request URL from an additional HTTP header you can end up with a different signature to the one Canvas generated.
This doesn't seem to be what's wrong in your case as you say your manually calculated signature matches what your code is generating. However it might be worth just checking. There's an article from Microsoft about this that might be useful: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3....
I am not aware of any other reasons which might cause this signature issue. Are you able to share an example message (including the full URL, POST data parameters and shared secret used to sign it) so that I can take a closer look?
Yes, thank you! So how things are set up right now, we're setting up a button in canvas that when we push it, we should be interacting with our external application.
the resulting page that I end up on after pressing the button has the full URL "https://leep-syl-canvas-preview.dev7.leepfrog.com/ribbit/?page=lti". I think this is the proper url to be using when constructing my base string, but i've also tried using the url where the button appears in canvas.
I'm attaching my logging output, which displays each parameter in the request. The param string and base strings are constructed and displayed. Then the hash string being used is displayed (clkey1234&clkey12345).
The signature is being generated by calling an hmac-sha1(baseString, hashString) function, and the resulting signature is matching the signature from lti-tools/oauth/, however we are not matching the oauth_signature value that comes from canvas.
I'm also including a screenshot of the xml i'm using to add the external tool to canvas. The xml is pretty much just what we see as the example in getting the oauth_compliant field set to true, but I don't believe I have a way to confirm that oauth_compliant is actually being set to true.
Sorry about the wall of text on this. Please let me know if you need any further information! Thanks again!
Thanks for the details. So are you saying that Canvas has been configured with a consumer key of "clkey1234" and a shared secret of "clkey12345" and a launch URL of "https://leep-syl-canvas-preview.dev7.leepfrog.com/ribbit/?page=lti" for the link being used?
Yes, thank you for confirming. I'm setting the key values manually in canvas when I add the external tool, and the launch url is set from the xml file.
I have been able to confirm the correctness of the OAuth signature being sent by Canvas using the site at http://lti.tools/oauth. So I believe any error must lie at your end. For example, make sure that you are URL-decoding any parameter values (and names).
Hey everyone, I have been following this thread in search of answers, and while I have managed to make my way through the signature process, I am officially blocked. I am currently using http://lti.tools/oauth/ to test the params I receive from Canvas, but I still get a different signature after inputing these details. From reading this post, here is what I have changed:
1. I removed all plus symbols from strings that have spaces, I read this from @NickStarr solution post
2. I have also made sure to remove any /' symbols as well
If I could get the signature to match in http://lti.tools/oauth/ , I think I'll be able to fix my algo and cater it to how @orhunk90 has laid out. I am using JavaScript to accomplish this. Could please help?
Okay, I believe I have figured it out. When inputing params in http://lti.tools/oauth/, be sure to add the spaces back that were included as "+" symbols. For example, "word+word+" would be "word word {space}". This was my problem. Hope this also helps!
To participate in the Instructure Community, you need to sign up or log in:
Sign In