Engine introduced LTI 1.1 platform support in version 20.1. The learning standard is well-implemented, but introducing customers to LTI 1.1 became a thorny issue. Unlike a learning standard like SCORM, we can't send sample LTI 1.1 packages for customers to import and play around with.
Unfortunately, Rustici Software doesn't own or maintain a test 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.1 capabilities as a platform. To try and address this need, this article explains the steps to import and launch LTI 1.1 links from the Saltire tool into Engine.
Configuring Engine
The Engine-side setup is pretty easy, as you only need to configure Engine's LtiConsumerIdentifier and LtiBaseUrl settings to get started. 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": "LtiConsumerIdentifier",
"value": "consumerId"
}
]
}
Configuring the Saltire Tool
1) Open the Saltire tool.
2) Leave the "Signature method" selection as "HMAC-SHA1".
3) For the sake of keeping things simple, you could also leave the tool's default "Key" and "Shared Secret" fields as "jisc.ac.uk" and "secret", respectively. It's fine to change these two values, but if you do, hit the "Save" button from the top, right-hand side and leave this page open throughout testing.
Importing LTI 1.1 Links
The easier way to import an LTI 1.1 link is with a POST request to api/v2/courses. Use the tool's "Key" field value for the "key" property and its "Shared Secret" field value for the "sharedSecret" value.
Based on the tool and configuration above, the JSON will look like this:
{
"lti11LinkReferenceRequest": {
"url": "https://saltire.lti.app/tool",
"key": "jisc.ac.uk",
"sharedSecret": "secret",
"title": "Hello World"
}
}
An LTI 1.1 link may also be imported via Content Connector. This is useful in cases where you have multiple links using the same credentials, as it allows you to specify the credentials in only one place. For more information, check out Engine's LTI v1.1 documentation.
Launching an LTI 1.1 Link
After configuring the tool and importing the course link, you can create and launch a registration as you would for any other course standard. If the launch process works, you should be taken to a success page:
Basic Outcomes
1) To test scoring, expand "Services Available" and choose "Basic Outcomes".
2) The "Endpoint" and "Result SourcedId" fields should have populated automatically. Notice that the "Endpoint" value is your LtiBaseUrl + "/v2/registrations/ltiBasicOutcomes", and the "Result SourcedId" is the full and serialized registration ID from Engine.
3) Set the "Outcome Value" to a value between 0 and 1 and click "Update".
Provided that the POST to Engine succeeds, you should be able to retrieve the score from the normal GetRegistrationProgress endpoint.
Common Issues
By far, the most common message in a failure response is "Could not verify oauth signed message". If this occurs, you'll see an error like this in the Engine log.
INFO 2021-10-25 17:05:26 UTC – OAuth header validation failed
RusticiSoftware.ScormContentPlayer.Util.Exceptions.InvalidArgumentException: net.oauth.OAuthProblemException: signature_invalid
oauth_problem: signature_invalid
oauth_signature: Zy/mXAk78nHTX9nic89kxIvlQYc=
oauth_signature_base_string: POST&http%3A%2F%2Frustici-engine.rutger.dev.mycademy.com%2FRusticiEngine%2Fapi%2Fv2%2Fregistrations%2FltiBasicOutcomes&oauth_body_hash%3DFa9D8LowXDDdJICnt%252BZK2AHdL9c%253D%26oauth_consumer_key%3Djisc.ac.uk%26oauth_nonce%3D00937c3379da9d661d19256e533cc178%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1635181525%26oauth_version%3D1.0
oauth_signature_method: HMAC-SHA1
When the LTI tool makes a request to Engine, it generates a signature for the request that takes into account all the details of it, including the URL (Engine's basic outcomes endpoint). Then, when Engine receives the request, it calculates its own signature and compares the two. If they are different, then you get the "signature_invalid" error. In short, the failure indicates a difference between the tool's original POST request URL and what actually made it to Engine for processing. This typically results from a reverse proxy or SSL termination sitting in front of Engine.
If using Java Engine, you can add the "X-Forwarded-Host" and "X-Forwarded-Proto" request headers to the request that reaches Engine. If present, Engine will use those to reconstruct the original request and build the OAuth 1.0 base string and signature. For .NET Engine, you have a few more options, which are covered here.