orhunk90
Community Novice

LTI OAUTH 1.0 Signature Mismatch

Jump to solution

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

Nonce: nYrB8fqYrLsKd4Q1QharrvjBYb9zj03unlAU7urXg
Timestamp: 1536243035
Generated signature: Iyxdh5swIDAro/K7WbUWAjhOUI0=

Signature comes from Canvas:  z2tzUWURgkf6m56L7wrUyqe50wE=

Currently, I am using this code to generate the OAuth signature: 

OAuth-Signature-Validation-Tool/OAuthBase.cs at master · mashery/OAuth-Signature-Validation-Tool · G... 

Thank you,

Tags (4)
1 Solution
Ok, i see now a few things. It looks like I need to have a space in the value for lis_person_name_full. It also looks like the page=lti needs to be added into the set of parameters. Additionally, it appears I was mistaken on how the keys need to be used (per your entries into the tool, the resulting hash string should just be 'clkey12345&'. Thank you so much for your help! With this I info I should be able to fix my implementation.

View solution in original post

0 Kudos
25 Replies
pklove
Community Champion

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.)

0 Kudos

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.

 

0 Kudos
veeresh_d
Community Member

Were you able to generate the correct oauth_signature from your end?

0 Kudos
svickers2
Community Contributor

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).

0 Kudos
NickStarr
Community Member

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.

0 Kudos
svickers2
Community Contributor

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.

Thank you so much for clarifying. I'm not clear on how to set the oauth_compliant property to true. Is this something that is handled from the Canvas User Interface as an Admin Account? Thanks again.
0 Kudos
svickers2
Community Contributor

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.

Ok, thank you for clarifying. I think I've set the oauth_compliant field to true now. To confirm, when this field is set, would we still expect the generated hash to match a hash generated by a tool like one at http://lti.tools/oauth?
0 Kudos
svickers2
Community Contributor

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).

Fantastic, thank you for sharing your knowledge on this! It is appreciated!
0 Kudos
NickStarr
Community Member

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!

0 Kudos

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....

0 Kudos
svickers2
Community Contributor

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?

0 Kudos

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!

0 Kudos
svickers2
Community Contributor

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?

0 Kudos
NickStarr
Community Member

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.

0 Kudos
svickers2
Community Contributor

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).

0 Kudos
Thank you for checking that. This doesn't match with my experience on my end. When I plug in the info for the request to the tool at lti.tools/oauth the generated signature does not match the signature that comes from canvas (the oauth_signature parameter), but does match the signature that I generate on my end labeled as Generated OAuth 1.0 Hash Signature in the .txt file i'd attached.

Am I understanding correctly that when you plug in my parameters to the lti.tools/oauth tool, your resulting signature matches the oauth_signature provided from canvas?

If so, could you please include a screenshot of your inputs at the top of the tool?

Thanks again for taking a look, it is greatly appreciated!
0 Kudos
svickers2
Community Contributor

Yes, that is correct, the system at lti.tools/oauth confirms the signature from Canvas.  See attached image of the entry forms I used.

Ok, i see now a few things. It looks like I need to have a space in the value for lis_person_name_full. It also looks like the page=lti needs to be added into the set of parameters. Additionally, it appears I was mistaken on how the keys need to be used (per your entries into the tool, the resulting hash string should just be 'clkey12345&'. Thank you so much for your help! With this I info I should be able to fix my implementation.
0 Kudos