LTI Client Side postMessages

LTI Client Side postMessages

Base Document
Spec Version 0.1
Base Document
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.2 OIDC Authorization URI origin

Requests secured by the login initiation origin must be sent to the origin of the pre-registered platform OIDC login initiation endpoint. If listening for a response to a postMessage initially secured by the login initiation origin, the tool must validate that the response origin also matches the login initiation origin.

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 code wrong_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 and subject 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: message event.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.
This is a preview of the 1EdTech LTI Client Side postMessages Specification

This preview is being provided to facilitate member communications around implementation of this solution to solve for the browser cookie problem.

B. List of Contributors

The following individuals contributed to the development of this document:

Name Organization
Peter Franza42 Lines Inc.
Eric PrestonBlackboard, Inc.
Claude VervoortCengage
Martin LenordTurnitin
Maggie SazioD2L Corporation
Viktor HaagD2L Corporation
Xander MoffattInstructure
Bracken Mosbacker1EdTech
Joshua McGhee1EdTech
Charles SeveranceUniversity of Michigan
Mary GwozdzUnicon, Inc.
Justin BallAtomic Jolt

1EdTech™ Consortium, Inc. ("1EdTech") is publishing the information contained in this document ("Specification") for purposes of scientific, experimental, and scholarly collaboration only.

1EdTech makes no warranty or representation regarding the accuracy or completeness of the Specification.

This material is provided on an "As Is" and "As Available" basis.

The Specification is at all times subject to change and revision without notice.

It is your sole responsibility to evaluate the usefulness, accuracy, and completeness of the Specification as it relates to you.

1EdTech would appreciate receiving your comments and suggestions.

Please contact 1EdTech through our website at www.1edtech.org.

Please refer to Document Name: LTI Client Side postMessages 0.1

Date: October 17th, 2022