Skip navigation
All Places > Canvas Developers > Blog > 2016 > September
2016

In .NET LTI Project - Part 2 - Launch Request we looked at the variables that are received in the launch request.  These variables are a vital part of user authentication using OAuth.

 

In very general terms, OAuth allows an authenticated user in Canvas to be identified and authenticated in your application.  Canvas will send you the identity of the user in the launch request, and you will use OAuth to verify that the identity sent to you has not be tampered with.  Once you have verified the integrity of the credentials you have received, you can masquerade as that user.

 

Consumer Key and Shared Secret

In the first article .NET LTI Project - Part 1 - Connect to Canvas we looked at how to connect your application to Canvas using the XML configuration.  Part of that process included the Consumer Key and Consumer Secret.  These two values now come into play.

 

In the launch request, Canvas will send you the Consumer Key which is a unique identifier.  Think of it as a user id.  If you are working with multiple institutions, or multiple applications, this would be the "user id" for each institution or application.  For example, if you are creating multiple LTI tools for your institution, this would be the unique id for each tool that you are exposing.  Or if you are supplying a tool to multiple institutions, this would be the unique id for each institution.

 

The Shared Secret is the password.  Canvas will never send you the Shared Secret, it is meant to be private, and should only be known by you and Canvas.  Canvas will use the Shared Secret to create an encrypted hash of the form parameters that are sent to you in the launch request as the oauth_signature.

 

When you receive the launch request, you will look at the variable oauth_consumer_key to lookup the shared secret on your end.  You will then use the Shared Secret to validate the OAuth signature found in the launch request parameter oauth_signature.

 

Make sure you understand the importance of the values Consumer Key and Shared Secret, and think about how you are going to store and retrieve them in your app.  What naming convention will you use to generate your Consumer Key and Shared Secret?  Would something like a GUID make sense, at least for the Shared Secret?

 

More Detailed OAuth Information

Here is a site that talks about the OAuth variables, and the sequence of operations in general.  This will give you some good information if you want to dig in and understand all of the steps involved:

 

As I wrote my own OAuth class, I ran into a wall and got stuck.  As I tried to figure out what I was doing wrong, I found this library:   DotNetOpenAuth

Note:  I did have to make an update to the code to properly handl URL encoding.  If you use this library, take the time to debug and understand the steps.

Having an example to illustrate is sometimes very helpful to get you over a hump, and this code helped me to find where I was missing an iteration of URL encoding.  If nothing else, working through this code might help to understand the steps involved, and see them in action.

 

If you decide to write your own OAuth algorithm, I suggest referencing this tutorial to validate your results:

If you can reproduce results from a known set of variables, you are well on your way.  This sandbox also discusses the basic requirements to generate the OAuth signature.

 

NOTE: Make sure you understand the security structure, and the role of the nonce and timestamp, and have a strategy to verify unique messages.  This is definitely not a "security how-to".

 

Why Fight It?  Find a library.

In the end I decided to use a library.  If someone has already taken the time to create and debug a well established technology, could it be more stable than my own home grown version?  I eventually found that IMS Global (the authority on LTI) has published sample code.  At that point I put my own library to bed, and adopted the IMS code.  They have sample code for multiple languages here:

Source code for this library can be found here:

Using this library, validating the OAuth signature is one line of code.  For ease of readability, and to call out the namespace where you can find the method of interest, this is a bit long winded:

 

bool signatureVerified = (LtiLibrary.Core.OAuth.OAuthUtility.GenerateSignature(request.HttpMethod, request.Url, request.Form, consumerSecret) == request.Form["oauth_signature"]);

 

When you receive the launch request, that's when you want to validate the OAuth signature.

Calling GenerateSignature and passing in the variables will return a string.  If that string does not match the string you received from Canvas in the oauth_signature variable, reject the request and do not allow the user to access your app.

 

 

In relation to the test project used in .NET LTI Project - Part 1 - Connect to Canvas you would use the line of code in your HelloWorld controller in the following methods:

  • Index() - which we configured to receive a launch request from the Account navigation menu
  • Welcome() - which we configured to receive a launch request from the Course navigation menu

You will need to validate the signature in any method where you are receiving a launch request from Canvas.

 

NOTE: Keep in mind, once Canvas has launched your app you will not recieve any more data from Canvas, your application runs on your server.  Something to think about and I'll cover some details to think about as we continue on.

 

It is also important to note that I am passing in the Consumer Secret.  This is the private key that is shared between you and Canvas, and is used to generate the hashed signature string.  You need to be able to look this value up based on where the request is coming from.  Again, if you have multiple institutions accessing your tool I strongly recommend having a unique Consumer Secret for each institution.

 

Perhaps the best reason to use a trusted library is that you are able to focus on your business logic, you are able to focus on the functions of your app, and not spend time rewriting well established logic.

 

Conclusion

So, validating the signature can be as simple as a single line of code.  Hurray!

But, you will learn a lot by writing your own if you have the time.

It should be easy to test your validation now:

  • Enter a different Consumer Key and Secret in Canvas vs. your app and make sure validation fails
  • Try sending the same nonce, how are you handling that?
  • Try sending an earlier timestamp, how are you handling that?
  • Try modifying other values sent in the Form params, does your signature still validate?
  • What does the user see if their request is rejected?

It is really up to you to flush out your test cases.

 

Getting past OAuth has been a topic of discussion in several places, I hope this helps.

There are several considerations once you get past authentication, I'll mention some of them in another post.

 

A basic Visual Studio project has been published here: LTI Demo Project

During a session at InstructureCon 2016 I realized that there are quite a few people who are interested in developing LTI tools for their institution, and looking for instruction on how to get started.  I thought maybe I could help, at least from a .NET perspective.

 

I do realize that Canvas lives on the *nix platform, but .NET is fully capable of communicating with it.  The department I'm in currently uses the Microsoft stack (except for virtualization).  So, for those of you out there who are also using Microsoft technology I hope to make this easy.  Those who are not using Microsoft tech will hopefully be able to at least follow along.

 

If you're diving into LTI I'm going to assume that you have a background in web application development in general, and will not get bogged down in setting up a development environment.  I will be happy to provide additional details later as needed, based on feedback.

 

What you will need...

I'll be working through this project using Visual Studio 2015, community edition should be fine.

 

You will need a web server to host your demo application, along with an SSL certificate.  LTI will not work over standard HTTP, you will need to use HTTPS.  I'll be using IIS for this role.

  • Use Google to find an article on creating a self-signed certificate if you do not have an SSL certificate available.

 

Common Starting Point

As a recommendation, I am going to use the project from this tutorial to work through the steps of launching an LTI app in Canvas.

I realize this is a simple tutorial, which is why I chose it for this task: I do not want to get bogged down in what the app actually does.  The focus here is really on how to wire up the LTI side of things, the app is almost irrelevant.

 

Note:  If you do follow along using this tutorial, add a default value for the "Name" parameter when you add the "Welcome" controller.  Or, remove the parameter completely.  You'll see why later.

 

Going through this process will give us a common point of reference.  For those who are more advanced, start from where ever you are comfortable, or whatever project you have in mind.  If you do nothing but implement the first three steps of the "Getting Started..." tutorial, you will have enough to launch your first LTI application in Canvas.  The key here is that through the process of creating the sample project, you have implemented methods capable of recognizing specific HTTP verbs, i.e. GET, PUT, POST, etc.  This is required in order to work with LTI.

 

Launching your first LTI tool

 

Step 1: Create the XML Application Definition

So, let's see how we can launch our new LTI tool in Canvas (we'll get into OAuth and user validation later).

The first thing we'll need is an XML file that defines our application, go to this URL to use a tool to help create your XML file:  XML Config Builder

 

For this example, we'll add launch points for our LTI app to the Account navigation, and to the Courses navigation.

Here is a description of how I completed the entry fields in the XML tool:

Options

  • Name:  ltiDemo
  • ID: <generated guid>
  • Description: Demo app to illustrate how to launch an LTI application in Canvas
  • LTI Launch URL:  https://ltidemo.mydomain.com/
  • Icon URL:  <blank>
  • Custom Fields:  <none>
  • Launch Privacy:  Public
  • Domain:  ltidemo.mydomain.com
  • Extensions:  select "Course Navigation" and "Account Navigation"

Course Navigation Settings

Account Navigation Settings

 

Click the "Generate XML" button, copy the results found under "XML Output", paste these results into an XML file in your project.  My file name is:  ltiDemo_config.xml

 

Step 2: Push the XML Configuration to Canvas

For the purposes of this simple demo, we will make the demo app available to the entire instance, i.e. all sub-accounts.

  • I strongly recommend using your test or beta instance of Canvas, log in to the instance of your choice
  • Click on Admin, and go to the Settings of your instance
  • Click on the "Apps" tab
  • Click on "View App Configurations"
    app-configuration.png
  • Click on "+ App"
    add-app.png
  • You should now have a pop-up view labeled "Add App"
    add-app-settings.png
    • Configuration Type:  select "Paste XML"
    • Name:  ltiDemo
    • Consumer Key:  ONE
    • Shared Secret:  TWO
    • XML Configuration:  copy your XML content and paste it into this entry field.
    • Click "Submit"

 

NOTE:  In this case I have used a meaningless Consumer Key and Shared Secret, I'll discuss these values in more detail in a later document.

 

Once you have completed these steps, under "External Apps" you should see "ltiDemo" listed.

If you refresh your Canvas browser window, you should now see "ltiDemo" in your Account navigation.

If you then browse into a course, you should see "ltiDemo" in your Course navigation.

 

Step 3:  Let's Test !

I'm going to assume that you are testing from your local development environment.  In this case, you will want to add an entry to your hosts file to handle local DNS lookup on your domain name.

For Windows users:  c:/windows/system32/drivers/etc/hosts

Edit this file and add the following line:

127.0.0.1  ltidemo.<yourdomain>.com

 

Save your change, then ping your domain and make sure you get a response.

 

Now when you request an LTI launch from the browser on your development machine, the URL of your demo app will be found on your local machine.

 

Refresh your Canvas browser page, and you should now see "ltiDemo" listed in your Account navigation options.

Looking back at our XML configuration, if you click "ltiDemo" at the Account level, it should launch the following URL in an iFrame within Canvas:  https://ltidemo.mydomain.com/helloworld/welcome

 

Now browse into any course, and you should see "ltiDemo" listed in the Course navigation options.

Looking back at our XML configuration, if we click "ltiDemo" from a course it should launch the following URL in an iFrame within Canvas:   https://ltidemo.mydomain.com/helloworld/

 

Conclusion

Launching your own tools inside Canvas is really not too hard once you know how to do it.

Keep in mind that we haven't addressed one ove the most favorite topics yet, which is OAuth.

However the goal here was simply to demonstrate how the launch is wired up, and show how to display your tool in an iFrame within Canvas.

 

I will begin working on Part 2, I hope this is helpful.

 

Part 2 is published here:  .NET LTI Project - Part 2 - Launch Request

A basic Visual Studio project has been published here: LTI Demo Project

Garth Egbert

API Testing: Postman

Posted by Garth Egbert Expert Sep 10, 2016

This information is really geared towards users who are trying to get started with the API.

 

I have seen questions in the community about the API, and have see Postman mentioned many times.  But, searching the Community I have not found any posts specifically about this tool and feel it might be worth talking about for those looking for a starting point.  My hope is that folks who are experienced with the tool can add to this information and further help new users get up to speed.

 

Postman Web App

Postman is easily accessible in Chrome through the Web Store.

If you haven't installed an app in Chrome before take a look at this article:

Install and manage apps - Chrome Web Store Help

 

To find the Postman web app and install it, search the Web Store for "Postman"

web-store-postman.png

 

Postman Native App

Postman also has a native app that you can install directly, which can be downloaded here:

Postman | Supercharge your API workflow

Personally I have not downloaded the native app yet, and have exclusively used the Chrome web app so far.

 

Postman provides documentation on installing the Chrome web app and the native app here:

Postman Docs - Getting Started

 

Authenticating With Your Token

To make an API call you will need to use your developer token to authenticate.

The following screen shot illustrates how to use the Headers to submit your token.

  1. Click on the "Headers" tab
  2. Enter the value "Authorization" for the key
  3. Enter "Bearer <token>" as the value

 

This screen shot also shows an example of the syntax to get a list of enrollments for a specific course, which you might want to use to test your token.

bearer-token.png

 

Example of a GET

You will need to tell Postman what type of API call you are making, i.e.GET, POST, PUT, whatever HTTP verb is associated with the API call.  The following screen shot shows an example of making a GET call to get the current status of an asynchronous job:  Progress - Canvas LMS REST API Documentation

 

In this case the API call is asking for the status of a content migration request.  You can see that GET has been selected as the type of API call being made, the authorization token has been provided, and the json results are displayed.

postman-get.png

 

Example of a POST

This is an example of a POST command to copy course content into another course:

Courses - Canvas LMS REST API Documentation

Notice in this screen shot that POST is selected.

postman-post.png

 

Example of a PUT

This might be useful, an API call to update a course:

Courses - Canvas LMS REST API Documentation

In this example, I am passing a parameter to publish/unpublish a course (which is useful in a script to publish all courses at the beginning of a semester).  Notice this time that PUT is selected in Postman.

postman-put.png

 

API Results

API results come back in JSON format.  JSON is notation representing object data.  If you are not familiar with JSON take a look at this W3Schools page for an overview:

JSON Syntax

 

W3Schools also has a tutorial here:

JSON Tutorial

 

Conclusion

This is basic info to help someone get started.  There is so much  more you can do.

Search Google for video walk-throughs to provide additional details.

Look through the Postman docs for tutorials and advanced techniques:  Postman Docs

 

Hopefully the info here will get you started, and community members will add their tips and tricks.

 

2016.11.14 - Update

If you would like to see source code showing how to implement the API in .NET, I have posted here:

For those who are interested in automating admin tasks and reporting, this might be useful.

When we were researching LMS platforms, one piece of feedback that really struck me as being obvious was course navigation.  What we found was consistent feedback from users who were frustrated that finding resources from one course to the next could be so dramatically different, why couldn't they find the same things in the same place from one course to the next?

 

This is something we really liked about Canvas.  Course navigation options are essentially the same from course to course.  We like that they can be re-organized to your liking, but unless you jump through hoops, it isn't easy to rename them or add random items that would make navigation unrecognizable to students across courses.  A feature that is a bonus in our  opinion.

 

During our planning, we talked to faculty to gather their thoughts and feedback on this issue.  The result was a base course template with a course navigation menu layout that, at the time, everyone was agreeable to.  Life was good, and everyone was happy.

 

And then there was the launch.  As we started to release courses for consumption, and faculty started to get comfortable with Canvas and learned how to modify their own order of navigation, things started to move around.  Course navigation options started moving all over the place, faculty were moving things around differently across courses they were teaching themselves, very strange.  I would think they would want to see things in the same place in each course, but, ok.

 

As we continue to provide support, post examples, and record video demonstrations, we need things to be in the same place so faculty can easily follow along with our screen shots and demo videos.

 

A specific example: recently a mandatory attendance policy was enforced.  We recorded a video to walk faculty through Roll Call, and realized that the "Attendance" option was all over the place across the courses.  This was for sure going to cause confusion among faculty who were already pushing back against using Canvas, we needed the "Attendance" option to be in the same position as seen in our training video.

 

And in comes the API.  I looked all over the API for "menu", "navigation", poured over the "course" API options, but couldn't find what I needed.  In the end, through a unrelated conversation thread, Jing Qi for directing me to the the content I needed.  There is an API to allow you to re-order your course navigation options:

Tabs - Canvas LMS REST API Documentation

 

Tabs??  Who knew??  Thank you Jing Qi !  I am not sure I would have ever looked at "tabs" related to "course navigation".

 

This API allowed us to create a script to easily move the "Attendance" option to a specific location in the course navigation, iterating this change across ALL courses, so faculty could more easily follow along with our training video, making our lives and theirs much easier.

 

As faculty start to further understand the benefits of having course options in the same places, we will be able to further standardize these options moving forward with simple scripts to automate adjustments across the board.

 

11.14.2016 - Update

For those using .NET, I have made a blog post and included source code showing how the Canvas API can be used in .NET.  This code can be modified to create custom workflow to automate admin tasks as reporting: