LTI Client Side postMessages
Spec Version 0.1
Document Version: | 4 |
Date Issued: | October 17th, 2022 |
Status: | This document is for review and comment by 1EdTech Contributing Members. |
This version: | https://www.imsglobal.org/spec/lti-cs-pm/v0p1 |
Latest version: | https://www.imsglobal.org/spec/lti-cs-pm/v0p1 |
Errata: | https://www.imsglobal.org/spec/lti-cs-pm/v0p1#revision-history |
IPR and Distribution Notice
Recipients of this document are requested to submit, with their comments, notification of any relevant patent claims or other intellectual property rights of which they may be aware that might be infringed by any implementation of the specification set forth in this document, and to provide supporting documentation.
1EdTech takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on 1EdTech's procedures with respect to rights in 1EdTech specifications can be found at the 1EdTech Intellectual Property Rights webpage: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf .
The following participating organizations have made explicit license commitments to this specification:
Org name | Date election made | Necessary claims | Type |
---|---|---|---|
D2L Corporation | July 21, 2022 | No | RF RAND (Required & Optional Elements) |
Use of this specification to develop products or services is governed by the license with 1EdTech found on the 1EdTech website: http://www.imsglobal.org/speclicense.html.
Permission is granted to all parties to use excerpts from this document as needed in producing requests for proposals.
The limited permissions granted above are perpetual and will not be revoked by 1EdTech or its successors or assigns.
THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTER'S OWN RISK, AND NEITHER THE CONSORTIUM, NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION.
Public contributions, comments and questions can be posted here: http://www.imsglobal.org/forums/ims-glc-public-forums-and-resources .
© 2022 1EdTech™ Consortium, Inc. All Rights Reserved.
Trademark information: http://www.imsglobal.org/copyright.html
Abstract
This is required.
1. LTI Client Side postMessages
This document describes the functionality of sending and receiving window postMessages used within the LTI specifications. Any messages send or received by a tool or platform should follow these rules to maintain interoperability and security whilst communicating.
LTI applications are often embedded within IFrame within the Learning Platform's main window. In order to offer a more integrated experience, it is desired to establish an in-browser communication between the IFrame and its host. This can range from purely UI experience like resizing of the frame to match the actual content, to storing state outside of the frame to offer an alternative to limitations imposed by browsers on 3rd party cookies. The messaging between cross domains documents is accomplished using windows postMessage API.
1.1 Glossary
For the rest of this document, the following definitions apply:
- Tool Frame: The iframe opened by the learning platform to launch the tool, or the window if the tool was launched in its own tab/window.
- Tool Frame Parent: The Tool Frame immediate parent or the window.opener if the tool was launched in its own tab/window.
- Target Frame: Frame to which should be sent messages. If defined, the target frame must be a direct child frame from the Tool Frame Parent.
- window postMessage - The
window.postMessage()
method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it. See Mozilla postMessage documentation.
2. Message Targets
Specifying the appropriate target origin and frame is essential to providing proper security for the postMessages between Platform and Tool.
2.1 Target window
In the case of a tool, unless specified otherwise by a message's documentation, the default target window is the parent window of the window the login initiation request was made to or the parent of the window the LTI message . If the parent window object is not available then the window opener should be used instead. If neither window objects are available then postMessage communication is not able to take place.
The target window can usually be determined in the following way through JavaScript:
let target_window = window.parent || window.opener;
In the case of a platform sending a new postMessage, the target window will be the window the login initiation request is made to.
In the case of a tool or a platform responding to a postMessage that it has received, the event source must be used as the window target unless specified otherwise.
The following JavaScript allows the fetching of the event source window:
window.addEventListener('message', function(event) {
// Validate message
let target_window = event.source;
// Send response postMessage
})
2.2 Target frame
The target frame is the window object to which a tool will actually send a postMessage. If not explicitly specified, the target frame is the same as the target window.
A platform may optionally provide the name of the target frame that must be used. The name must refer to a named child of the target window. The name may be passed to the tool via either a query parameter or the capabilities discovery request.
The target frame can be determined in the following way through JavaScript:
let target_window = window.parent || window.opener;
let target_frame = get_target_name() ? target_window.frames[get_target_name()] : target_window;
2.3 Target origin
When making a postMessage request, a target origin must be specified to prevent potentially sensitive information from being sent to a malicious party. Each message type will indicate the requirement for securing the origins of the request.
2.3.1 Wildcard origins
Requests sent to the wild card origin *
must be explicitly described to do so in their respective documentation. Incorrect use of the wild card origin can be dangerous, potentially leaving an application vulnerable to XSRF or man in the middle attacks.
2.3.3 Tool redirect origin
Requests secured by the tool redirect origin must use the origin of the pre-registered return url used in the active launch flow. If listening for a response to a postMessage initially secured by the tool redirect origin, the platform must validate that the response origin also matches the pre-registered redirect origin used for the initial message.
2.3.4 3rd party login initiation origin
Requests secured by the 3rd party login initiation origin must be to the origin of the pre-registered tool third party login initiation url. If listening for a response to a postMessage initially secured by the third party login initiation origin, the platform must validate that the response origin also matches the third party login initiation origin.
3. Request/Response using windows postMessage API
Interactions with the Learning Platform often follow a Request/Response paradigm; the tool sends a postMessage request message, and the platform responds through another message, which may just be to notify the message was successfully processed. While the current model always as the tool as the request originator, it may be possible future interactions will involve the platform being the originator of the request. In either case, the following rules apply:
3.1 Request parameters:
- All messages value must be a Javascript Object.
- Each request must be sent to the Tool Frame Parent unless the message specifies a Target Frame, in which case the message must be sent to that frame.
- Each request message must contain a
message_id
property with an identifier uniquely identifying this request. - Each request message must contain a
subject
property with the message type identifying the interaction. Subject values are specified in each message specification document.
3.2 Response parameters:
- Each response message must contain the
message_id
property with the identifier value from the request it is responding to. - Each response message must contain the
subject
property. Its value must be the value of the request's subject with the.response
suffix appended. - Each response must be posted to the window from where originated the request (i.e. the
event.source
window)
3.2.1 Error response parameters:
- If an error in the processing of the request occurred, the platform response must respond to the tool with an error. The response must contain an
error
property. The error value must be a Javascript Object with the following properties:code
: required, an error code for the error. This specification defines a few error codes; message specifications may declare additional codes relevant to the operation.message
: optional, a human readable message explaining the error.- Message specifications may define additional properties for the error object.
- If the error is due to unsupported subject, the platform must reply immediately using the error code
unsupported_subject
. - If the request
event.origin
is coming from an unexpected origin, the recipient must reply immediately using the error codewrong_origin
. - Platform must communicate success even if the message type does not require a value to be sent back in the response. In which case the response message may just contain the
message_id
andsubject
properties.
3.3 Error codes
This specification defines the following error codes. This is an open vocabulary. Message specifications and platforms may define additional codes relevant to their operation when more applicable.
unsupported_subject
: subject is not supported.wrong_origin
: messageevent.source
is not authorized to send that message.bad_request
: the request properties are not valid and the message cannot be processed.error
: a generic error code indicating an error during the processing of the message, to be used when there is not a more specific code available.
3.4 Example postMessages
These examples show the basic format of the post-messages. Any service built on top of these base messages will have their own properties defined within the specification documents describing them.
3.4.1 Request (Tool)
Base message format for request message format:
{
"subject": "lti.example",
"message_id": "12345",
...
}
3.4.2 Response (Platform)
Base message format for a response message
{
"subject": "lti.example.response",
"message_id": "12345",
...
}
OR Base message format for an error response
{
"subject": "lti.example.response",
"message_id": "12345",
"error": {
"code": "bad_request",
"message": "A specific useful error message"
}
}
4. Defining LTI Client Side postMessages
This document defines how to establish a secure communication channel between LTI Platform and Tool to send window postMessages but leaves the definition of those messages to separate specification and best practice documents. The LTI Workgroup will define and publish postMessages that a Platform or Tool could support. Additionally a Platform or Tool may define their own messages.
The Capabilities Request postMessage is the only message defined in this document and is required to be implemented by LTI Platforms providing LTI Client Side postMessages.
4.1 Capabilities Request postMessage
This describes the rules for request/response style communication and how it is used to allow a platform to advertise its messaging capabilities i.e. which messages are supported and if there is any restriction on how they need to be accessed.
A tool may at runtime discover the front-end capabilities from the Learning Platform by issuing a request to the parent window. This allows the tool to have a deterministic understanding of the supported interactions rather than relying on heuristic like timeout on message responses to infer no support for messages.
4.1.1 Immediate response
Since the tool may not know if the learning platform actually support the capability query request, it is required for platforms implementing support of this message to respond immediately. Tool should set a very small timeout period (in the order of a few milliseconds) before considering this message is not supported by the platform. Therefore a platform should make sure it is able to respond to that request prior to launching the Tool. For example, a platform should not execute any network query in the process of handling the request for capabilities.
4.1.2 Target Origin
Since this is a discovery message not exposing any sensitive information, the tool should target the message to the Iframe immediate parent with the wildcard * origin. Platform must not filter the incoming request by origin. However, as with any request/response message flow, the response must be posted to the window from where the request originated from.
4.1.3 Subject
The Subject is: lti.capabilities
4.1.4 Supported Messages
The response must contain the supported_messages
property. The value is an array of Supported Message definition objects.
4.1.5 Supported Message
A Supported Message object contains the following properties:
subject
: required, a String value with the subject of the supported message as included in the subject field of the actual message.frame
: optional, a String with the name of the IFrame that should receive the message. If present, messages must be sent to this Iframe using the provided name, for example:window.parent.frames[name].postMessage(...)
. If not present, message must be sent to the IFrame immediate parent (or the window opener in case of non embedded launch).
A message specification may describe additional properties to be included in the Supported Message definition for messages of that type.
4.1.6 Example capabilities messages
4.1.6.1 Tool requests capabilities
First, the LTI tool would send a capabilities request that would look like this:
window.parent.postMessage({
"subject": "lti.capabilities",
"message_id": "12345"
}, "*")
The platform will then respond, and either specify a target frame for future tool post-messages or not. As an LTI tool you MUST be able to make requests under both scenarios.
4.1.6.2 Platform responds with no target frame name
{
"message_id": "12345",
"subject": "lti.capabilities.response",
"supported_messages": [
{
"subject": "lti.capabilities"
},
{
"subject": "lti.example"
}
]
}
4.1.6.2.1 Tool requests to parent frame
To utilize a supported service the tool would send to the target frame like this:
window.parent.postMessage({
"subject": "lti.example", ...
}, ...)
4.1.6.3 Platform responds with a target frame name
{
"message_id": "12345",
"subject": "lti.capabilities.response",
"supported_messages": [
{
"subject": "lti.capabilities"
},
{
"subject": "lti.example",
"frame": "platformFrameName"
}
]
}
4.1.6.3.1 Tool requests to a target frame name
To utilize a supported service the tool would send to the named target frame like this:
window.parent.frames["platformFrameName"].postMessage({
"subject": "lti.example", ...
}, ...)
4.1.7 Messages target origin and valid origin
Refer to the relevant message specification to understand which origin to use.
A. Revision History
Document Version No. | Release Date | Comments |
---|---|---|
3 | July 21, 2022 | First release of LTI Platform Storage Base Doc. |
4 | October 17th, 2022 | Completion of initial IP review to make documents publicly available. |
B. List of Contributors
The following individuals contributed to the development of this document:
Name | Organization |
---|---|
Peter Franza | 42 Lines Inc. |
Eric Preston | Blackboard, Inc. |
Claude Vervoort | Cengage |
Martin Lenord | Turnitin |
Maggie Sazio | D2L Corporation |
Viktor Haag | D2L Corporation |
Xander Moffatt | Instructure |
Bracken Mosbacker | 1EdTech |
Joshua McGhee | 1EdTech |
Charles Severance | University of Michigan |
Mary Gwozdz | Unicon, Inc. |
Justin Ball | Atomic Jolt |