Do I need OAuth for my external tool?

584 views
Skip to first unread message

Eric Kean

unread,
Apr 25, 2013, 10:03:17 AM4/25/13
to canvas-l...@googlegroups.com
Hello,

I minimally understand OAuth as a means of securing connections between 3rd party apps with Canvas.  However, I'm not quite sure if I need it and would appreciate some input.  Basically, my website is an External Tool within Canvas.  Once they click on the link to my site through Canvas, I then check to see if $_REQUEST['lti_message_type'] == 'basic-lti-launch-request'.  If it does, I look in my database to see if their Canvas userid exists.  If it doesn't, I then have them log into my site using their username and password form my site. If it matches someone in my site, I then update that user with their Canvas userid in my database so that in the future, when they click on my External Tool through Canvas, their id will be in my system and they'll be logged into my site automatically.

Are there any "obvious" security issues?  And, more importantly, do I need OAuth?

Thanks so much,

Eric

Chris Herdt

unread,
Apr 25, 2013, 10:21:54 AM4/25/13
to canvas-l...@googlegroups.com
A user could forge such a request to your system, sending the lti_message_type and any Canvas user ID. You definitely cannot rely on the request parameters alone to authenticate users.


--
 
---
You received this message because you are subscribed to the Google Groups "Canvas LMS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to canvas-lms-use...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Chris Herdt
Web Applications Developer
267-603-1066 (home)
734-754-3585 (cell)
http://osric.com/chris/

Christopher Bennell

unread,
Apr 25, 2013, 11:14:58 AM4/25/13
to canvas-l...@googlegroups.com
To elaborate on Chris' comment, you should verify the OAuth signature and nonce/timestamp before you trust the request. 

Brian Whitmer

unread,
Apr 25, 2013, 12:39:54 PM4/25/13
to canvas-l...@googlegroups.com
Really the only time you don't need to verify the OAuth signature is if you don't have any user sessions as part of your app. If you were just relying on your own cookies then you could ignore all the LTI parameters, but that would kind of defeat the purpose of using LTI at all. Since you're taking the Canvas User ID from the launch and matching it to a value in your local db, you're trusting that the ID is valid, so you need to verify the signature. 

-Brian


--
 
---
You received this message because you are subscribed to the Google Groups "Canvas LMS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to canvas-lms-use...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--

  

Eric Kean

unread,
Apr 25, 2013, 2:01:28 PM4/25/13
to canvas-l...@googlegroups.com
Thanks guys!  I guess that it does make sense that someone could just $_POST a forged request as indicated by Chris.  And, since I do have sessions with my own app it looks like I'll have to use OAuth as Christopher points out.  After doing some OAuth investigating, I found this intro post and downloaded the the code that Dr. Chuck created. I then downloaded his code from google code. Are there any php'ers who have used it for OAuth in connection with LTI?  Dr. Chuck seems like one of the "go-to-guys" but I'm a bit nervous to use his code as it uses mysql_query instead of PDO or mysqli so I'm not quite sure if it's current.  To add more confusion, there seems to be an OAuth as part of Canvas' API so I'm not quite sure where to begin.

Any help getting me started with an appropriate OAuth class would be appreciated.

-Eric

Brad Humphrey

unread,
Apr 25, 2013, 10:56:41 AM4/25/13
to canvas-l...@googlegroups.com
To clarify, you can use the request parameters to authenticate users, but you also need to confirm that the request originated from a trusted source.  LTI uses OAuth 1.0 to establish the authenticity of requests to tool providers.  The security works like this: When you set up an LTI you are required to provide a shared secret.  The tool consumer (Canvas) will then use this secret to sign the POST request to the 3rd party tool.  The tool can then generate the same signature using the shared secret to confirm that the request originated from a trusted source.

Generally there are libraries available to do all of the confirmation magic for you.  Then, once you have confirmed the authenticity of the request, you are able to safely authenticate the user as you described in your email.

As a side note this OAuth is completely separate from the OAuth2 authentication that Canvas uses for API access.


       

Christopher Bennell

unread,
Apr 26, 2013, 12:33:19 AM4/26/13
to canvas-l...@googlegroups.com
I've used Zend Framework components to verify OAuth requests. I'll share some code on Monday :)

Eric Kean

unread,
Apr 26, 2013, 3:54:39 AM4/26/13
to canvas-l...@googlegroups.com
Brad,

Thank you for a very clear "big picture" description of the process.  Now I can at least wrap my head around it!

Eric Kean

unread,
Apr 26, 2013, 3:58:39 AM4/26/13
to canvas-l...@googlegroups.com
Christopher,

That would be fantastic!  I've used ZF1 components for session stuff and my database connection; integrating the OAuth component for the verification process with Canvas would really work well for me.

Enjoy your weekend...

-Eric


Eric Kean

unread,
Apr 28, 2013, 10:14:27 AM4/28/13
to canvas-l...@googlegroups.com
For Anyone who is interested:

After some head banging this weekend, I figured out how to do the oAuth implementation using a predefined class.  Hopefully, this can help some future noob like myself. You can go to http://code.google.com/p/ims-dev/source/checkout to download the class code (not written by me).  And, if you're doing things in PHP:

1.  Have an instructor add their Consumer Key and Secret to the 3rd party External Tool (see Canvas for documentation).
2.  On the landing page of your site:
require_once ('path/to/php_simple/ims_blti/blti.php'); //this is from the file that you grab from google
$context = new BLTI("Secret", false, false); //the Secret is your actual secret and can be loaded from a database.  Your secret and the instructor's secret must be the same
if (!$context->valid) {
echo "You don't belong here!"; //kick em' out since they don't have the proper oAuth signature
exit;

That's it!  And if you'd like to see a demo of what goes on, then instead of the above code, on your landing page, send them to tool.php (again from the downloaded google code).  Anyway, I do appreciate the thoughts of the contributors to my original question.  Hopefully this extra tidbit can help someone else move things along.

-Eric

Christopher Bennell

unread,
May 1, 2013, 10:30:33 AM5/1/13
to canvas-l...@googlegroups.com
It sounds like you might not need this anymore, but here's the code I'm using to validate signatures and authenticate users: https://gist.github.com/christopher-b/5495515

It's a Zend_Auth_Adapter implementation, so it can be used as a plugin for an existing Zend_Auth setup. However there are a few quirky things specific to my app that won't work out of the box with other apps, like the way the table gateway is created. Would require some tweaking. 

You may also just be interested in this part, which actually generates a signature: 

$signer = new Zend_Oauth_Signature_Hmac($consumer->secret, null, 'sha1');
return $signer->sign($this->_getRequestParams(), Zend_Oauth::POST, $this->_getOAuthUrl());

Eric Kean

unread,
May 1, 2013, 10:38:05 AM5/1/13
to canvas-l...@googlegroups.com
Christopher,

I am in fact good to go.  However, I appreciate your taking the time to send me this link and it very well could help out someone else in this forum.

Cheers!

-Eric

Steve

unread,
Nov 15, 2013, 3:49:59 PM11/15/13
to canvas-l...@googlegroups.com
Hi Brad - 
Hi - Rather than start a new thread I wanted to see if you might be able to shed some additional light on a problem I'm having validating an oauth signature that's being passed into my external tool from a Canvas call.  I've set up a testing program to help me quickly run through various permutations of parameters, so that my generated signature matches what Canvas is passing in, but no match yet. 

Here's some knowns and unknowns:

Knowns: 
1. Canvas passes in a timestamp and nonce. 
2. I've created the external tool call in Canvas, and provided the consumer key and shared secret.
3. I'm seeing the consumer key as a parameter passed from Canvas.
4. Using oauth version 1.0 although I've tried 2.0
5. http method is POST, although I've also tried permutations with GET
6. encryption method is HMAC-SHA1

Unknowns:
1. Canvas does not pass in an oauth_url as a parameter.
2. I'm creating the value of the oauth_url by using the exact URL string (https://[toolsite]/page) that I'm typing into Canvas when creating the tool (so the tool location). I've also tried using the URL of the tool as seen when the user hovers their mouse over the tool link on the left hand side (https://[site].instructure.com/courses/[number]/external_tools/[number], but that didn't generate a match either.
3. Canvas is not sending out any member token as a parameter, nor did it appear necessary to create any since there is no data that will be passed back to Canvas from this tool, so my function is using blanks for the token values, which appears a standard/OK option.

 Tnx for any advice. I'm using vb.net and have found some apparently reliable code posted elsewhere, and have traced it through.

Steve

Becky Kinney

unread,
Nov 15, 2013, 7:24:29 PM11/15/13
to canvas-l...@googlegroups.com
I don't think you absolutely NEED oAuth, but without it, you wouldn't truly know that the person was coming to you from Canvas. Anyone can link to your site with  POST variables that match what you are expecting. With oAuth, you have a way to check that the secret (which is not a POST var) matches whatever you have distributed to your tool adopters. In any case, I don't see that there is any reason not to implement oAuth. You don't have to write the code yourself. Just grab a library. If you are using php, try downloading dist.zip from this page http://ims-dev.googlecode.com/svn-history/r437/trunk/basiclti/php-simple/. The zip has oAuth and BLTI classes, and some nice sample pages to get you started. For a minimal authentication scheme, the code should work for you right out of the box.

Good luck, and let us know how you make out.
Becky Kinney
Academic Technology Services

Brad Humphrey

unread,
Nov 18, 2013, 12:03:27 PM11/18/13
to canvas-l...@googlegroups.com
I have recently developed a tool for troubleshooting the signing process.  It is basically a tool launch proxy that takes a request from canvas, lets you enter an endpoint, key, secret, etc, and then shows you the signature base string, signing key, and signature.  It then allows you to submit the signed request to your tool where you can compare all of these things to what my tool generated.

You can install the tool using any key/secret, and the configuration here: https://lti-tool-provider.herokuapp.com/tool_config.xml?signature_proxy_test=1

Just a quick disclaimer, this tool is only in beta.  I have done some testing and used this tool to troubleshoot a handful of integrations, but there could still possibly be bugs in the signature generation.  Also, if anyone wants to contribute or finds any issues free to contribute at https://github.com/instructure/lti_tool_provider_example.


       


Reply all
Reply to author
Forward
0 new messages