Simple LTI Tool Consumer in HTML and JavaScript

Will Wolff-Myren
Learning.com Tech Blog
4 min readJan 17, 2018

What is LTI?

From Recipe for Making LTI 1 Tool Providers | IMS Global Learning Consortium:

LTI (Learning Tools Interoperability®) provides a standard mechanism for authorizing users accessing a web-based application (Tool Provider) from another web-based application (Tool Consumer, typically an LMS). It can be seen as replacing a login page which a Tool Provider may otherwise have provided and avoids the need to distribute a username and password to each user. Instead a signed launch message is received from the Tool Consumer which can be verified and then trusted. This message should contain sufficient data from which to create user accounts and relevant resources (or resource mappings) “on-the-fly”. Users gain a seamless experience without the need for any pre-provisioning, involvement of any other servers (for example, identity providers), or changing of any firewalls (message is sent through the user’s browser). LTI works best when the Tool Provider delegates full responsibility for authorizing users to the Tool Consumer and does not allow users to directly access their system, thereby bypassing this authorization. This means that there is no need for the two systems to be synchronized with any changes to user privileges, so there is no risk of a user being given access to resources to which they are no longer entitled.

Example Code

For this example, I’ve implemented a simple LTI 1.0 Tool Consumer (TC) within a static HTML page, using JavaScript to generate the non-static form post parameters: Simple LTI Launch Test

This TC includes the bare minimum required fields to construct a valid LTI launch. In this case, the generated launch will post to the saLTIre LTI Tool Provider emulator, which is capable of validating our launch request.

If you open the developer tools on the Simple LTI Launch Test page, you’ll see that both the form and the script have been logged to the console.

Expanding <script> tag in the console shows the script used to generate <form> above, as well as the logic that generates the values for the oauth_nonce, oauth_timestamp and oauth_signature fields. For convenience, the script is also included here:

This script uses the oauth-sign npm module to generate a valid HMAC-SHA1 signature from the params collection, then adds the signature value to a new property in params, called oauth_signature. Then, the entire collection of params is used to populate the action attribute and the <input> nodes in the form with id ltiForm, as we can see by expanding the <form> in the console. For convenience, an example is included below:

OAuth 1.0a

IMS Global Learning Tools Interoperability™ Basic LTIv1 Implementation Guide | IMS Global Learning Consortium

Basic LTI uses the OAuth protocol (http://www.oauth.net) to secure its message interactions between the TC and TP. OAuth requires a key and shared secret to sign messages. The key is transmitted with each message, as well as an OAuth-generated signature based on the key. The TP looks up the secret based on the provided key and re-computes the signature and compares the recomputed signature with the transmitted signature to verify the sender’s credentials.

Per section 4.2 of the LTI 1.0 specification Basic LTI Message Signing and the OAuth 1.0a specification, the following OAuth fields are required for a valid OAuth 1.0a request:

  • oauth_consumer_key
  • oauth_nonce
  • oauth_signature_method
  • oauth_timestamp
  • oauth_version
  • oauth_signature

LTI 1.0

The parameters required for a valid LTI request are a superset of those required for a valid OAuth request. In other words, you will need at least the fields listed above, as well as the required LTI fields listed below:

Minimum required fields for LTI launch request

  • lti_message_type (always: basic_lti-launch-request)
  • lti_version (always: LTI-1p0)
  • resource_link_id

While these fields are indeed the minimum required fields for a valid LTI launch request, the following additional fields are recommended by the specification, with some of the following fields being required by certain LTI Tool Providers:

  • resource_link_title
  • user_id
  • roles
  • context_id
  • context_title
  • context_label
  • launch_presentation_document_target
  • launch_presentation_width
  • launch_presentation_height
  • launch_presentation_return_url
  • tool_consumer_instance_guid
  • tool_consumer_instance_name
  • tool_consumer_instance_contact_email

The following additional fields are recommended unless they are suppressed because of privacy settings:

  • lis_person_name_given
  • lis_person_name_family
  • lis_person_name_full
  • lis_person_contact_email_primary

Looking Forward: LTI Advantage

In a future post (after the LTI 1.3 spec is finalized), I’ll be reviewing the new OAuth 2 + JWT authentication and signature methods required in LTI 1.3 and LTI Advantage.

Issues with LTI 1.x’ OAuth 1.0a signature method

(tl;dr — SHA1 is insecure, OAuth 1.0a is outdated)

LTI 1.3+ OAuth 2 / JWT

IMS Global Learning Consortium Contributing Members who are leading the evolution of LTI have responded to market concerns about student data privacy and security by adopting the industry standard protocol OAuth2 for authenticating services along with JSON Web Tokens (JWT) for secure message signing.

New certification requirements in 2018

Additional Reading

--

--