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.
View movie illustration - Installing and using the application (56 seconds)
View movie illustration - Accessing services and launching other tool providers (2:39 minutes)
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:
- 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.
- 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.
- 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.
- 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):
- LTI launch request from an LTI tool consumer to a web-based LTI tool provider
- Redirect from web-based tool provider to launch a native application
- 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):
- confirm the validity of the launch request message by verifying its OAuth parameters;
- 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);
- save a copy of the LTI launch parameters (excluding the OAuth parameters) so they can be made available to the native application on request
- 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;
- 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:
- check for a command-line parameter which may contain an access token;
- base64-decode the access token;
- 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:
- check the access token is valid and not expired;
- 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;
- return a JSON object containing the new access token and the LTI launch parameters received in the original launch request (excluding any OAuth parameters);
- 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 URL | http://www.spvsoftwareproducts.com/win/wintp/connect.php or http://www.spvsoftwareproducts.com/win/wintp/connect.php/jwt |
Consumer key | jisc.ac.uk |
Shared secret | nativeapp |
LTI launch request issued by tool consumer
Launch parameters:
Name | Value |
---|---|
oauth_version | 1.0 |
oauth_nonce | 368bb7dafa3e99eacb442ac7721c0419 |
oauth_timestamp | 1431206401 |
oauth_consumer_key | jisc.ac.uk |
lti_message_type | basic-lti-launch-request |
lti_version | LTI-1p0 |
resource_link_id | 429785226 |
resource_link_title | Phone home |
user_id | 29123 |
roles | Instructor |
lis_person_name_full | John Logie Baird |
lis_person_name_family | Baird |
lis_person_name_given | John |
lis_person_contact_email_primary | jbaird@uni.ac.uk |
lis_person_sourcedid | sis:942a8dd9 |
context_id | S3294476 |
context_type | CourseSection |
context_title | Telecommuncations 101 |
context_label | ST101 |
lis_course_offering_sourcedid | DD-ST101 |
lis_course_section_sourcedid | DD-ST101:C1 |
tool_consumer_info_product_family_code | jisc |
tool_consumer_info_version | 1.2 |
tool_consumer_instance_guid | vle.uni.ac.uk |
launch_presentation_return_url | http://lti.tools/test/tc-return.php |
launch_presentation_locale | en-GB |
launch_presentation_document_target | frame |
oauth_callback | about:blank |
oauth_signature_method | HMAC-SHA1 |
oauth_signature | wy4EI5umuopH3cfEXa9cLWyxNyQ= |
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", }
and a payload of:
{ "sub" : "www.spvsoftwareproducts.com" "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:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3d3cuc3B2c29mdHdhcmVwcm9kdWN0cy5jb20iLCJpYXQiOiIxNDMxMjA2NDAxIiwiZXhwIjoiMTQzMTIwNjQ2MSIsIm9yZy5pbXNnbG9iYWwubHRpLmRhdGFfdXJsIjoiaHR0cDovL3d3dy5zcHZzb2Z0d2FyZXByb2R1Y3RzLmNvbS93aW4vd2ludHAvZGF0YS5waHAvYjJlM2Q0ZjEwZWE2Y2Y1NDNmMTNlNThhNDRiOTA0MzIifQ.R8hL-9X63Cgcs7SiEOf-Irnnaks0F2NXXPZky4N4jDM
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:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3d3cuc3B2c29mdHdhcmVwcm9kdWN0cy5jb20iLCJpYXQiOiIxNDMxMjA2NDAxIiwiZXhwIjoiMTQzMTIwNjQ2MSIsIm9yZy5pbXNnbG9iYWwubHRpLmRhdGFfdXJsIjoiaHR0cDovL3d3dy5zcHZzb2Z0d2FyZXByb2R1Y3RzLmNvbS93aW4vd2ludHAvZGF0YS5waHAvYjJlM2Q0ZjEwZWE2Y2Y1NDNmMTNlNThhNDRiOTA0MzIifQ.R8hL-9X63Cgcs7SiEOf-Irnnaks0F2NXXPZky4N4jDM
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:
custom_chapter=3
custom_page=45
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
- The launch can be further secured by encrypting the JWT before it is passed to the native application.
- The native application should take suitable measures to obfuscate the secret(s) used to verify the incoming JWT so that its confidentiality is maintained.
- 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:
- a section describing the services being made available
- an access token to use when making service requests
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
Version | Date | Description |
---|---|---|
1.0.0.0 | 9 May 2015 | Initial release |
1.1.0.1 | 14 February 2017 | Added revised workflow using JWT |
1.2.0.1 | 3 April 2017 | Added 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.