Engine introduced LTI 1.3 platform support in version 20.1. The learning standard is well-implemented and passed IMS Global certification testing as a certified LTI v1.3 Learning Platform. Nevertheless, introducing customers to LTI 1.3 became a thorny issue. Unlike a learning standard like SCORM, we can't send sample LTI 1.3 packages for customers to import and play around with.
Unfortunately, Rustici Software doesn't own or maintain a testing suite for LTI. There are some online resources dedicated to this, but they aren't always user friendly. At best, they'll give you a feel for what's required to configure Engine and LTI courses. Generally speaking, it's better to test with the tool you plan on using, as there tend to be differences among the various tools, and commercial, non-test ones are typically less fiddly. Of course, we understand that this isn't always possible, and developers simply want an easy way to verify and test Engine's LTI 1.3 capabilities as a platform. To try and address this need, this article explains the steps to import and launch LTI 1.3 links from the IMS test tool in Rustici Engine.
Configuring Engine
1) First, configure the following settings in Engine:
You can configure these inside the RusticiEngineSettings base configuration file or with a system-level POST request to the V2 API's /api/v2/appManagement/configuration endpoint:
{
"settings": [
{
"settingId": "LtiBaseUrl",
"value": "http://HostName/RusticiEngine/api"
},
{
"settingId": "RemoteDeliverPageUrl",
"value": "http://HostName/RusticiEngine/defaultui/player"
},
{
"settingId": "LtiPlatformIssuer",
"value": "https://www.example.com"
},
{
"settingId": "LtiConsumerIdentifier",
"value": "consumerId"
}
]
}
Creating an IMS Test Tool
1) Go to the tools page and select "Add Tool". Keep this tab open.
2) Go to the generate keys page. Keep this tab open as well.
3) Copy the private key from the generate keys page into the "Private Key" field in the tool. For now, use a unique but easy-to-remember value for the "Name" field. We'll update it along with the rest of these values after we create an LTI 1.3 connector in Engine.
4) Once the page resembles the image below, press "Create Tool".
Creating an LTI 1.3 connector
1) Go back to the main tool page and click on the "Unclaimed Tools" tab to locate your created tool. You should see a bunch of URLs like this:
2) Make a POST request to /api/v2/contentConnectors. This can be a system or tenanted request, and the request body will look like this:
{
"contentConnectorType": "ContentConnector.Lti13",
"configuration": {
"toolPublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqpKDidh73S9vcp6N2Dv8\nEz5m6bkBpvAVYYqXKret/niYMqgxHgZ9qamurl5fBFlXGd0r9dgDVLmzgywJGcNa\nKVDmIJjjOMLMww51e7LgMHu8TngSgbAGlHgG4bTxwNjs8Z8dn68GI/ne8tuD+0K+\neNmcu0K2hpbkhHBcLnFtnjQAd1vj8bL3UYhyEMydqjHlx9SMhHpABiGbO3w94uRa\nUV2i6TP6zT3FeoN65ZhnmNH/dlaER1vS2oTM5nkWzaKdnQfq6AYRKxILzBHEANjg\nFlV1tLG+GsS8zrxXPjSxGbcFwpqI9MkBIfdNhboJEK3ogle+rd+xZEpsgBtmVMvC\ncQIDAQAB\n-----END PUBLIC KEY-----",
"toolOidcLoginInitiationsEndpoint": "https://lti-ri.imsglobal.org/lti/tools/1128/login_initiations",
"toolOidcLaunchRedirectUris": ["https://lti-ri.imsglobal.org/lti/tools/1128/launches"]
}
}
The "toolPublicKey" property value should be the public key from the generate keys tab. Keep in mind that you must remove the newlines and replace them with "\n" to make it one continuous string. Online tools for this task are easy enough to find, but you could just as easily use a text editor and replace the newlines with "\n".
The "toolOidcLoginInitiationsEndpoint" property value should be the "Tool OIDC Login Initiation URL", and the "toolOidcLaunchRedirectUris" should be a list containing just the "Tool launch URL".
3) Make note of the connectorId in the response, as you'll need this for the next step:
{
"result": "64e9264d-9407-4195-81b8-d8c1a0a9e7fb"
}
Configure the Test Tool
1) Once the connector has been successfully created, make a GET request to api/v2/contentConnectors?includeAdditionalInstanceInformation=true and locate the connector that was just created. If used in the previous POST request, use the same "EngineTenantName" request header.
2) Press the "Edit" button on your tool and then fill in the fields with the following values from the "additionalInstanceInformation" schema returned by the API request.
AdditionalInstanceInformation | Test Tool |
---|---|
toolClientId | Name |
toolClientId | Client Id |
deploymentId | Deployment |
jwksEndpoint | Keyset URL |
accessTokenUrl | Oauth2 URL |
oidcAuthorizationUrl | Platform OIDC Auth URL |
Once configured, the tool should look something like this:
3) Press "Update Tool" to save your changes.
Import an LTI 1.3 link
1) Make a POST request to /api/v2/courses. Use the same connectorId from the previous steps for the JSON body's "connectorId" property. The "url" property should be the "Tool launch URL" (the same value from the "toolOidcLaunchRedirectUris" property and used in the tool's "Platform OIDC Auth URL" field). To utilize Assignment and Grades Services, also include a "contextId" property. The request should look something like this:
{
"connectorReferenceRequest": {
"connectorId": "c010b8ba-6065-4d7f-b869-307481bb3fa9",
"metadataForConnector": {
"url": "https://lti-ri.imsglobal.org/lti/tools/1128/launches",
"title": "Title for my link",
"ltiMetadata": {
"description": "A test link",
"context": {
"contextId": "testContext"
}
}
}
}
}
Launching an LTI 1.3 link
1) Create and launch a registration for the course created in the previous steps.
2) You should be redirected to a page that looks like this:
3) Next, hit "Send Request" at the bottom of the page.
4) You should finally be taken to a page that looks like this:
If it says "Successful Launch", you're all done!
Assignment and Grades Services
Unfortunately, as of this writing, there are a few caveats to using this tool's Assignment and Grade Services feature. First off, the feature requires an IMS site account. Secondly, the tool has a breaking limitation, as IMS's implementation doesn't account for URLs that have query parameters (and Engine's does), so the tool ends up using an invalid URL for the POST request and causes a 404 error. Fortunately, for the purpose of verifying that Engine supports Assignment and Grade Services, there are a few workarounds.
Manually Make the Request
1) Instead of relying on the IMS tool, you manually can send the Assignment and Grade Services data to Engine with a POST request. To start, scroll down to the "Claims" section on the launch page. Locate the "lineitem" property; this will help to construct the request URL.
It's going to look like this:
http://ff56-24-183-235-66.ngrok.io/RusticiEngine20/api/v2/plugin/lti13/64e9264d-9407-4195-81b8-d8c1a0a9e7fb/testContext/lineItems/15994%7C%7Cdefault?externalConfig=
2) To fix it, replace "?externalConfig=" with "/scores?externalConfig=" to come up with the final request URL:
http://ff56-24-183-235-66.ngrok.io/RusticiEngine20/api/v2/plugin/lti13/64e9264d-9407-4195-81b8-d8c1a0a9e7fb/testContext/lineItems/15994%7C%7Cdefault/scores?externalConfig=
3) The content-type must be "application/vnd.ims.lis.v1.score+json".
4) And the body should look like this:
{
"userId": "{{scorm_registration_id}}||default",
"scoreGiven": 78,
"scoreMaximum": 100,
"comment": "Great work",
"timestamp": "2020-09-10T19:51:09Z",
"activityProgress": "Completed",
"gradingProgress": "FullyGraded"
}
Unfortunately, {{scorm_registration_id}} is an internal identifier that isn't normally surfaced. You can obtain this value from the launch page's "Security Details" JSON:
Alternatively, you can also find this value from the "userId" property in the response from the GetRegistrationProgress endpoint's "lti13SubjectIdentifier" property.
5) And finally, you can authenticate this request by using the basic auth credentials used for other V2 API requests.
Leverage Ngrok
Alternatively, if you're testing with a locally hosted instance of Engine and exposing it to the internet through a tool like Ngrok, you can use its "Web Interface" feature to modify and resend the corrected POST request.
1) After having signed in, hit the "Submit Score to Platform" button:
2) Open another browser tab and access Ngrok's "Web Interface" feature.
3) Find the POST request that resulted in a 404. It should look something like this:
POST /RusticiEngine/api/v2/plugin/lti13/64e9264d-9407-4195-81b8-d8c1a0a9e7fb/testContext/lineItems/15954||default
4) In the details to the right, there should be a "Replay" button. Choose the "Replay with Modifications" option.
5) Add "/scores?externalConfig=" to the end of the URL and hit "Replay".
Reading Scores
After making a successful Assignment and Grade Services POST to Engine, you should be able to query the GetRegistrationProgress endpoint and see the completion status and score.