Overview

WinTP is a Windows desktop client application which can be opened via an LTI launch request. It provides a simple environment for testing connections to native LTI tool providers by demonstrating how launch credentials can be securely passed to a native application.
Flash movie View movie illustration - Installing and using the application (56 seconds)

System requirements

The WinTP application is written for Windows XP (or later). The source code for the application is not currently available.

Installation

The WinTP application may be installed by downloading the installation program. Running the file will install the application and add an entry to the start menu and an icon to the desktop. The application can be uninstalled via the Windows Control Panel.

Usage

When the application is opened directly in Windows, a login form is displayed. In this example, it accepts any username with a password of nativeapp just as an illustration of how the application could be opened directly as well as via LTI.

The installation process associates the application with a URL protocol of ltitp. Opening the application in this way involves the following steps:

  1. Perform an LTI launch request to http://www.spvsoftwareproducts.com/win/wintp/connect.php (or http://www.spvsoftwareproducts.com/win/wintp/connect.php/jwt for the revised JWT-based proposal) with any consumer key and a secret of nativeapp; ensure that the launch includes a user_id parameter.
  2. After verifying the launch request, the script redirects the user to a URL of ltitp:<token>, where token a unique, single-use, short-lived ID which the application can use to exchange for the launch parameters.
  3. When the WinTP application is opened from the browser, it sends a POST request to the tool provider web server including the access token provided and receives a JSON document of the launch parameters in return. The token can only be used once, but a new access token is also included in the response which can be used in any further requests.
  4. The LTI launch parameters can be used by the application to identify the user and provide functionality appropriate to the context.

Proof of concept workflow

This application is intended as a proof of concept. It comprises three main elements which are appropriate for any native application (in this case, a Windows exectutable file):

  1. LTI launch request from an LTI tool consumer to a web-based LTI tool provider
  2. Redirect from web-based tool provider to launch a native application
  3. Native application requests LTI launch parameters from web-based tool provider

This process enables a native application to have access to the LTI launch data just as would be the case if it were web-based.

LTI launch request

The launch request is a standard LTI launch message requiring a launch URL, consumer key and secret to configure it. The launch URL should be to a script which does the following (as per the example script specified above):

  1. confirm the validity of the launch request message by verifying its OAuth parameters;
  2. ensure the launch parameters include a user_id parameter (this requirement could be relaxed if anonymous access is to be permitted to the native application);
  3. save a copy of the LTI launch parameters (excluding the OAuth parameters) so they can be made available to the native application on request
  4. generate an access token to send to the native application - this token should be a unique string but only needs to be short-lived, the value is base64-encoded before adding to the redirect URL to avoid any complications arising from URL-encoding;
  5. redirect the user sending the launch request to the native application (using the associated URL protocol) and include the access token in the URL.

Redirection to native application

When the user is redirected to a URL with the registered protocol, it should cause the browser to open the native application and pass in the encoded access token from the URL as a command-line parameter. When the native application is launched it should do the following:

  1. check for a command-line parameter which may contain an access token;
  2. base64-decode the access token;
  3. send a POST request message to the web-based tool provider with a JSON body containing the access token; this request is not signed, the access token confirms the identity of the sender.

Sending LTI launch parameters to native application

The access token supplied when redirecting the user to the native application should be exchangeable for the LTI launch parameters received from the original launch request. The process of responding to such a request is as follows:

  1. check the access token is valid and not expired;
  2. immediately expire the access token so it cannot be re-used and generate a new one which can be used by the sender for any future requests;
  3. return a JSON object containing the new access token and the LTI launch parameters received in the original launch request (excluding any OAuth parameters);
  4. the native application can use the LTI launch parameter data to identify the user, the context of the original launch, the user's role in that context, it will also provide an indication of the services made available by the tool consumer, though access to these would need to be via the web-based tool provider since the native application is not party to the consumer key and secret used to establish the trust relationship with the tool consumer.

An example launch

Tool configuration

Launch URLhttp://www.spvsoftwareproducts.com/win/wintp/connect.php or http://www.spvsoftwareproducts.com/win/wintp/connect.php/jwt
Consumer keyjisc.ac.uk
Shared secretnativeapp

LTI launch request issued by tool consumer

Launch parameters:

NameValue
oauth_version1.0
oauth_nonce368bb7dafa3e99eacb442ac7721c0419
oauth_timestamp1431206401
oauth_consumer_keyjisc.ac.uk
lti_message_typebasic-lti-launch-request
lti_versionLTI-1p0
resource_link_id429785226
resource_link_titlePhone home
user_id29123
rolesInstructor
lis_person_name_fullJohn Logie Baird
lis_person_name_familyBaird
lis_person_name_givenJohn
lis_person_contact_email_primaryjbaird@uni.ac.uk
lis_person_sourcedidsis:942a8dd9
context_idS3294476
context_typeCourseSection
context_titleTelecommuncations 101
context_labelST101
lis_course_offering_sourcedidDD-ST101
lis_course_section_sourcedidDD-ST101:C1
tool_consumer_info_product_family_codejisc
tool_consumer_info_version1.2
tool_consumer_instance_guidvle.uni.ac.uk
launch_presentation_return_urlhttp://lti.tools/test/tc-return.php
launch_presentation_localeen-GB
launch_presentation_document_targetframe
oauth_callbackabout:blank
oauth_signature_methodHMAC-SHA1
oauth_signaturewy4EI5umuopH3cfEXa9cLWyxNyQ=

Original proposal for Tool Provider implementation

On receipt of the above sample launch request, the Tool Provider would check its validity in the normal way, before then responding to the request.

Tool provider response to launch request

The tool provider generates an access token (d87e33ba5a23734636a1354f3c68769b in this example), base64-encodes it (giving ZDg3ZTMzYmE1YTIzNzM0NjM2YTEzNTRmM2M2ODc2OWI=) and redirects the user to a URL of ltitp:ZDg3ZTMzYmE1YTIzNzM0NjM2YTEzNTRmM2M2ODc2OWI=.

Native application opened by browser

When the browser receives the redirection it opens the native application (WinTP in this case) with a command-line parameter of the encoded access token (ltitp:ZDg3ZTMzYmE1YTIzNzM0NjM2YTEzNTRmM2M2ODc2OWI=). The native application base64-decodes the command-line parameter to extract the access token. It then uses the access token to send a POST request to the web-based tool provider server to obtain a copy of the LTI launch parameters. For example, the request message in this example was as follows:

POST /win/wintp/data.php HTTP/1.1
Host: www.spvsoftwareproducts.com
Content-Type: application/json
Accept: application/json

{
  "token" : "d87e33ba5a23734636a1354f3c68769b"
}

Tool provider response to request for LTI launch parameters

If the request from the native application contains a valid access token (which has not expired), it replaces the token with a new one (f3eaf8c242ee2186ff9826066a861327 in this case), extracts the parameters from the original launch request (excluding the OAuth parameters) and returns them in a JSON object:

{
  "token" : "f3eaf8c242ee2186ff9826066a861327",
  "launch_parameters" : {
    "context_id" : "S3294476",
    "context_label" : "ST101",
    "context_title" : "Telecommuncations 101",
    "context_type" : "CourseSection",
    "launch_presentation_document_target" : "frame",
    "launch_presentation_locale" : "en-GB",
    "launch_presentation_return_url" : "http://lti.tools/test/tc-return.php",
    "lis_course_offering_sourcedid" : "DD-ST101",
    "lis_course_section_sourcedid" : "DD-ST101:C1",
    "lis_person_contact_email_primary" : "jbaird@uni.ac.uk",
    "lis_person_name_family" : "Baird",
    "lis_person_name_full" : "John Logie Baird",
    "lis_person_name_given" : "John",
    "lis_person_sourcedid" : "sis:942a8dd9",
    "lti_message_type" : "basic-lti-launch-request",
    "lti_version" : "LTI-1p0",
    "resource_link_id" : "429785226",
    "resource_link_title" : "Phone home",
    "roles" : "Instructor",
    "tool_consumer_info_product_family_code" : "jisc",
    "tool_consumer_info_version" : "1.2",
    "tool_consumer_instance_guid" : "vle.uni.ac.uk",
    "user_id" : "29123"
  }
}

Native application receives LTI launch parameters

In response to its request, the native application receives the launch parameters and can use them to establish a session for the user.

Revised proposal for Tool Provider implementation

On receipt of the above sample launch request, the Tool Provider would check its validity in the normal way, before then responding to the request.

Tool provider response to launch request

The tool provider generates a JWT (JSON Web Token) with a header of:

{
  "typ" : "JWT",
  "alg" : "HS256",
  "kid" : "www.spvsoftwareproducts.com"
}

and a payload of:

{
  "iat" : "1431206401",
  "exp" : "1431206461",
  "org.imsglobal.lti.data_url" : "http://www.spvsoftwareproducts.com/win/wintp/data.php/b2e3d4f10ea6cf543f13e58a44b90432"
}

The JWT is signed using a secret (anativeapp in this example) to generate a JWT of:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ind3dy5zcHZzb2Z0d2FyZXByb2R1Y3RzLmNvbSJ9.eyJpYXQiOiIxNDMxMjA2NDAxIiwiZXhwIjoiMTQzMTIwNjQ2MSIsIm9yZy5pbXNnbG9iYWwubHRpLmRhdGFfdXJsIjoiaHR0cDovL3d3dy5zcHZzb2Z0d2FyZXByb2R1Y3RzLmNvbS93aW4vd2ludHAvZGF0YS5waHAvYjJlM2Q0ZjEwZWE2Y2Y1NDNmMTNlNThhNDRiOTA0MzIifQ.zeK7Y9Qa2AIuPJ6dYaRZfNnGwvrwZKuRd7q0l3cOemY

The secret used should be specific to the connection between the tool provider and its native application; it should not be the same as the one used to secure the connections with the tool consumer.

The tool provider then appends the JWT to the URL schema for the native application and redirects the user to the resulting URL:

ltitp:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ind3dy5zcHZzb2Z0d2FyZXByb2R1Y3RzLmNvbSJ9.eyJpYXQiOiIxNDMxMjA2NDAxIiwiZXhwIjoiMTQzMTIwNjQ2MSIsIm9yZy5pbXNnbG9iYWwubHRpLmRhdGFfdXJsIjoiaHR0cDovL3d3dy5zcHZzb2Z0d2FyZXByb2R1Y3RzLmNvbS93aW4vd2ludHAvZGF0YS5waHAvYjJlM2Q0ZjEwZWE2Y2Y1NDNmMTNlNThhNDRiOTA0MzIifQ.zeK7Y9Qa2AIuPJ6dYaRZfNnGwvrwZKuRd7q0l3cOemY

When the browser receives the redirection it opens the native application (WinTP in this case) with a command-line parameter of the signed JWT. The native application verifies the signature of the JWT, checks the exp claim to ensure it has not expired and extracts the value of org.imsglobal.lti.data_url element from the payload. It then sends a GET request to the extracted URL to obtain a copy of the LTI launch parameters. For example, the request message in this example was as follows:

GET /win/wintp/data.php/b2e3d4f10ea6cf543f13e58a44b90432 HTTP/1.1
Host: www.spvsoftwareproducts.com
Accept: application/json

The URL contains a one-use, short-lived token to identify the source of the request and its authenticity.

Tool provider response to request for LTI launch parameters

If the request from the native application is to a URL which has not expired or been used before, it extracts the parameters from the original launch request (excluding the OAuth parameters) and returns them in a JSON object. All custom and ext parameters are included in elements of those names and without their prefix. For example, if the message included the following custom parameters:

they would be represented in the JSON response as:

{
  ...
  "custom" : {
    "chapter" : "3",
    "page" : "45"
  },
  ...
}

Any parameters which comprise comma, separated lists (such as the roles parameter) are expanded into a JSON array.

{
  "org.imsglobal.lti.message" : {
    "context_id" : "S3294476",
    "context_label" : "ST101",
    "context_title" : "Telecommuncations 101",
    "context_type" : "CourseSection",
    "launch_presentation_document_target" : "frame",
    "launch_presentation_locale" : "en-GB",
    "launch_presentation_return_url" : "http://lti.tools/test/tc-return.php",
    "lis_course_offering_sourcedid" : "DD-ST101",
    "lis_course_section_sourcedid" : "DD-ST101:C1",
    "lis_person_contact_email_primary" : "jbaird@uni.ac.uk",
    "lis_person_name_family" : "Baird",
    "lis_person_name_full" : "John Logie Baird",
    "lis_person_name_given" : "John",
    "lis_person_sourcedid" : "sis:942a8dd9",
    "lti_message_type" : "basic-lti-launch-request",
    "lti_version" : "LTI-1p0",
    "resource_link_id" : "429785226",
    "resource_link_title" : "Phone home",
    "roles" : {
      "Instructor"
    },
    "tool_consumer_info_product_family_code" : "jisc",
    "tool_consumer_info_version" : "1.2",
    "tool_consumer_instance_guid" : "vle.uni.ac.uk",
    "user_id" : "29123"
  }
}

Additional top-level elements may be included in the JSON response to accommodate bespoke requirements. For example, a token might be included which can used to authorize further web service requests to the tool provider.

Native application receives LTI launch parameters

In response to its request, the native application receives the launch parameters and can use them to establish a session for the user.

General notes

  1. The launch can be further secured by encrypting the JWT before it is passed to the native application.
  2. The native application should take suitable measures to obfuscate the secret(s) used to verify the incoming JWT so that its confidentiality is maintained.
  3. The tool provider must ensure that the data URLs it issues can only be used once and are only valid for a short period of time (based on the expected time taken to launch the native application and generate the request to the data URL) so as to minimize the risk of the redirect being hijacked by a rogue application.

Using services

A tool consumer may make available access to one or more services in its launch message. This application implements a proposal for a mechanism by which a native application could utilise these services. It involves two additions to the JWT payload described above:

For example, the following JWT makes the Basic Outcomes service available to the native application:

{
  "org.imsglobal.lti.message" : {
    ...
  },
  "org.imsglobal.lti.service" : {
    "Outcomes.LTI1" : "http://www.spvsoftwareproducts.com/win/wintp/service.php"
  },
  "token" : "MmYwOTc2YzA0YjIwMzNhYTZmZ"
}

The elements within org.imsglobal.lti.service associate the name of a service with the endpoint to which to send the service request. The endpoint may be the same for every service, but this is not a requirement. Each service request is an HTTP POST request and must include the token in the Authorization header; for example, the following request will read the user's grade from the tool consumer:

POST /win/wintp/service.php HTTP /1.1
Host: www.spvsoftwareproducts.com
Authorization: Bearer MmYwOTc2YzA0YjIwMzNhYTZmZ
Content-Type: application/json
Content-Length: 54

{
  "service" : "Outcomes.LTI1",
  "action" : "read"
}

The request is sent via a script on the tool provider's website which can use the access token to associate the request with a specific launch. It will invoke the appropriate service request to the tool consumer using the data included in the JSON message body received. Its response to the native application is of the following form:

{
  "outcome" : "0.3"
}

The update and delete actions of the service would be access in a similar manner, using request bodies such as:

{
  "service" : "Outcomes.LTI1",
  "action" : "update",
  "outcome" : "0.5"
}

and

{
  "service" : "Outcomes.LTI1",
  "action" : "delete"
}

A tool provider may adopt its own proprietary format for making service requests; but following a standard approach, as proposed here, would allow a tool provider to delegate this functionality to a third-party service.

Launching other tool providers

It may be useful for a native application to be able to launch other tool providers. In this case, the JWT sent to the native application will include details of any tool providers which it is allowed to launch. For example,

{
  "org.imsglobal.lti.message" : {
    ...
  },
  "org.imsglobal.lti.service" : {
    ...
  },
  "token" : "MmYwOTc2YzA0YjIwMzNhYTZmZ",
  "tool_url" : "http://www.spvsoftwareproducts.com/win/wintp/tool.php",
  "org.imsglobal.lti.tool" : {
    "testtp" : "Test TP"
  }
}

In the above example, a tool with an ID of testtp can be launched by the native application but would be displayed to the user, where applicable, as "Test TP". Since the application being launched could be either web-based or native, the launch is performed through an auto-submitted web form in the same way as a web-based application would submit a launch message. The form would comprise a JWT with a header of:

{
  "typ" : "JWT",
  "alg" : "HS256"
}

and a payload of:

{
  "iat" : "1431206401",
  "exp" : "1431206581",
  "iss" : "WinTP.exe",
  "token" : "MmYwOTc2YzA0YjIwMzNhYTZmZ",
  "tool" : "testtp"
}

The payload would be signed using a secret known only to the native application and the JWT passed to the URL supplied in a form element named jwt. Submitting this form will cause the tool provider (or third-party) endpoint to submit a standard LTI launch request to the selected tool provider (using the consumer key and secret agreed between the parties). This may cause the the tool provider to be opened within a web browser, or it may lead to a native application being opened in the same way as the application initiating the launch was opened.

An issue remaining to be resolved is to identify what parameters should be included in the launch request. For example, should the roles from the original launch request which opened the native application be passed through as-is? What identity values should be used for the tool consumer instance, user, context and resource link?

Version history

VersionDateDescription
1.0.0.09 May 2015Initial release
1.1.0.114 February 2017Added revised workflow using JWT
1.2.0.13 April 2017Added support for services and launches

Licence

This work is written by Stephen Vickers and is released as shareware. You can use this link to download the installer for WinTP.

Valid XHTML 1.0 Strict