SSP LTI Provider
Overview
SSP v2.5.2 and later ships with an implementation of an IMS LTI v1.0 Tool Provider (TP). This allows for point-to-point, inbound SSO into SSP in much the same way as the legacy "Signed URL SSO" mechanism, but in a standards-compliant fashion. The LTI standard is so widely adopted that the SSP team expects LTI to quickly become SSP's most commonly used inbound SSO protocol for tool-to-tool integrations since it typically requires no custom code development.
This document describes the configuration process for enabling the TP and adding Tool Consumer (TC) profiles to it.
See here for a description of the technical implementation and more detail on the supported tool launch API.
Original JIRA ticket was:
Enabling the Tool Provider
The SSP LTI TP leverages SSP-Platform infrastructure originally built for the legacy "Signed URL SSO" mechanism. Platform protects that infrastructure by requiring non-embedded clients (such as SSP) to present a shared secret whenever invoking the newly shared API. This secret is set to the empty string by default, which effectively disables both the Signed URL SSO and LTI TP.
To set the secret on the Platform side, edit $SSP_CONFIGDIR/ssp-platform-config.properties
:
environment.build.sso.local.sharedSecret=<some-value>
Set that same value on the SSP side by editing $SSP_CONFIGDIR/ssp-config.properties
:
ssp_platform_sso_ticket_service_shared_secret=<some-value>
<some-value>
needn't be terribly complex. Something similar to an ATM pin should be sufficient.
Configuring a Tool Consumer
Tool Consumer Configuration Step 1 - Navigate to "LTI Consumers" Admin Tool
To see data in this tool, the current user must have the API_KEY_READ
permission. To change/add data, they need API_KEY_WRITE
. Be conservative in granting these permissions, especially the latter, because it allows users to create "back doors" to the application via OAuth2 Client configuration.
Click the "Add" button to add a new LTI Consumer:
Tool Consumer Configuration Step 2 - Complete the LTI Consumer Creation Form
Adding a new Consumer definition defines the connection between the LTI Provider and SSP. You will need to know the Lti person identifier and section code field in order to complete the form. A newly defined Consumer will create the person record in the SSP database based on the Consumer Name and Key values.
- The
Consumer Name
field is a friendly name to identify the Consumer - The
Consumer Key
field will actually be stored in theperson.username
column in the SSP database. As such:- Expect the value you enter to be forced to lower case, and
- Be sure to pick a value which will not conflict with a "real" end user's username
- The TC must know what its
Consumer Key
is for the SSP TP. Because TP's are ultimately responsible for ensuring each real-world TC integrated with it has a uniqueConsumer Key
, it is often up to the TP to specify to the TC what theConsumer Key
should be. But this can be a collaborative process.
- The
Consumer Secret
is also shared with and possibly arrived at via negotiation with the TC. The SSP TP implementation enforces no strength restrictions on this field other than that it must be non-empty. But in practice it should be at least as strong as whatever institutional requirements are placed on end-user passwords and likely stronger than that, since it is used for establishing an application-to-application trust relationship that allows the TC to assume the identity of any user. Because of the nature of LTI security, this value must be stored in plain text in both the TP and TC. - Set the
Lti User Id Field
to the name of the LTI launch parameter in which the TC will send the launching end user's identifier. The correct value to place here may not be known until you start to experiment with the TC. (Most TC implementations offer some sort of mechanism for snooping on TP launch requests so you can see which launch parameters are being passed.) - Use the
SSP User Attribute
combo box to specify the type of end user identifier SSP should expect to receive from the TC inLti User Id Field
, eitherusername
orschoolId
. - Use the
Lti Section Code Field
to specify the LTI launch parameter in which the TC will uniquely identify the course in which the end user was present when she initiated the launch. If the launch URL in the TC is configured to target the Early Alert portlet, the values sent in this launch parameter must match values loaded into thesection_code
field inexternal_faculty_course
andexternal_faculty_course_roster
SSP database tables.
Many of the field in the form offer additional help when you hover over field labels.
Click 'Save' to create the LTI TC:
Tool Consumer Configuration Step 3 - Browse the Updated LTI Consumer List
If the save was successful, the new TC list should resemble the following:
Tool Consumer Configuration Step 4 - Edit the LTI Consumer
If you decide you need to make changes to the TC, double click the corresponding row in the list view.
Deleting the secret will effectively disable the TC, as will deselecting the Active
checkbox.
Testing a Tool Consumer
Each TC implementation will have its own unique process for configuring a TP record, so documenting those clickpaths is outside the scope of this document. In general, though, the TC configurer will need to know the:
Consumer Key
- Configured aboveConsumer Secret
- Configured above- Launch URL - See below
SSP LTI Tool Provider Launch URLs
SSP launch URLs are of this form:
<base>/ssp/api/1/lti/launch/{launch-mode}</target/{target-id}>
launch-mode
is required. There are two supported launch-mode
values:
live
- Sends end user to requested SSP user interfacetest
- Returns diagnostic information about the launch request handling as JSON
The /target/{target-id}
fragment is optional. There are several supported target-id
values:
default
- Sends user to her default Platform portletea
,ea.roster
- Sends user to the Early Alert portlet's roster view, preselecting the specified roster, if any. If a roster is specified, but it cannot be found or is otherwise inaccessible to the launching user, the launch will succeed, but the Early Alert portlet will display an error message and an option to see all rosters for the current user.ea.form
,ea.new
- Sends user to the Early Alert portlet's Early Alert submission form. Not typically useful for a OOTB LTI integration because it requires passing the targeted student's identity, not just the launching user's identity.ssp
- Sends the user to the SSP portletmygps
- Sends the user to the MyGPS portletreports
- Sends the user to the Reports portlet
If the user does not have permissions to render the specified portlet, she will be sent to her default portlet.
If the launch itself fails for any reason in live
launch-mode
, the user will receive a brief error message and an error code. If proved to system administrators, that error code can be correlated with stack traces in the SSP logs, which will provide detail on exactly what went wrong.
When launched in test
launch-mode
the TC will return a 200 status code and a JSON document structured as follows:
{ "result_code": <string>, // Either 'OK' or 'FAILURE' "result_description": <string>|null }
If the launch was successful, result_description
will contain the URL to which the end user would have been redirected in live
launch-mode
. In the launch was unsuccessful, result_description
will contain a slightly more detailed message than live
mode, but logs will still need to be consulted for complete detail.
For example, the simplest "live" URL, which will attempt to redirect the end user to her default SSP user interface:
https://ssp.institution.edu/ssp/api/1/lti/launch/live
The corresponding "test" URL:
https://ssp.institution.edu/ssp/api/1/lti/launch/live
To target the Early Alert portlet with a "live" launch:
https://ssp.institution.edu/ssp/api/1/lti/launch/live/target/ea
Ad Hoc Tool Consumer Testing
Charles Severance's online LTI testing tool is often a fine starting point for verifying the TP configuration independently of the "real" TC you intend to use. The online version is often sufficient for simple configurations leveraging standard LTI launch params. For more complex usages, you may need to hack and run the PHP source locally:
- https://source.sakaiproject.org/svn/basiclti/trunk/basiclti-docs/resources/docs/sakai-api-test/
- https://github.com/csev/sakai-lti-test/
Common Problems
Offloaded SSL - If SSL connections terminate outside of Tomcat, e.g. in Apache or your load balancer, the SSP TP will refuse to authenticate launch requests unless Tomcat is tricked into thinking it is actually receiving SSL requests. This is typically done by adding the following attributes to the <Connector>
in <tomcat>/conf/server.xml
responsible for receiving traffic from the SSL termination point:
scheme="https" proxyPort="443" secure="true"
404 After Launch - The launch itself doesn't seem to error out and the user is redirected to a /ssp-platform
URL, but gets a 404 at that location. This is often caused by one or more of the following being misconfigured in SSP_CONFIGDIR/ssp-platform-config.properties
:
environment.build.uportal.server=ssp.institution.edu environment.build.uportal.protocol=https environment.build.uportal.context=/ssp-platform
Launch Failures or Target Failures - Messages in the SSP log (<tomcat>/logs/ssp.log
by default) should describe the technical problem associated with launch failures without requiring any special logging configuration, especially for 'test' launches. If you are not seeing such logs, try increasing the log level for the LtiLaunchErrorHandler
component. In SSP_CONFIGDIR
/logback.xml
:
<logger name="org.jasig.ssp.util.security.lti.LtiLaunchErrorHandler" level="warn" />
If the problem seems to have to do with the target receiving unexpected launch parameters or the launch failure suggests a problem with unexpected LTI launch parameters and the TC's request debugging tools are insufficient, try increasing logging in the OAuth package. In SSP_CONFIGDIR
/logback.xml
:
<logger name="org.springframework.security.oauth" level="debug" />
In particular, look for messages containing the string "Verifying signature", which won't provide an unprocessed view onto the original launch parameters, but will give you a very good idea of what all was in the original request.
The Tomcat RequestDumperValve
is another option for getting at the original request in a less processed format, although it can have side-effects which may disrupt the LTI message authentication process.
Moodle Isn't Sending the Launch Parameters I Need
OOTB, Moodle's LTI Tool Consumer does not send a value SSP can use as either a username
or a schoolId
. Workarounds:
Use Email Address Instead - Moodle does send a
lis_person_contact_email_primary
launch parameter which can be used to look up Platform accounts, assuming values in that field uniquely identify users in your SSP deployment. To this end, starting with SSP 2.5.3 and 2.6.0, SSP's Tool Consumer configuration UI allows you to setprimaryEmailAddress
in the 'SSP User Attribute' field. Use that value whenever setting 'Lti User Id Field' tolis_person_contact_email_primary
. Also, if you've configured SSP Platform to source user attributes from either a custom database table or AD/LDAP, you'll likely need to add an entry to the<queryAttributeMapping>
element in<platform-src>uportal-war/src/main/resources/properties/contexts/personDirectoryContext.xml
:<entry key="primaryEmailAddress" value="{physical-mail-attribute-name}"/>.
The local default uPortal DAO now includes that configuration for locally provisioned Platform accounts. Specifically:<entry key="primaryEmailAddress" value="mail"/>
The correct value for
physical-mail-attribute-name
will depend on the details of the external attribute source with which you are integrating and may be different for each DAO. If you are currently mapping a logical attribute namedprimaryEmailAddress
on the "value-side" of a DAO's<resultAttributeMapping>
property, you should use the "key-side" of that mapping as{physical-mail-attribute-name}
(this is exactly how the local default uPortal DAO is currently configured). I.e.<property name="queryAttributeMapping"> <map> <!-- snip --> <entry key="primaryEmailAddress" value="mail"/> <!-- snip --> </map> </property> <property name="resultAttributeMapping"> <map> <!-- snip --> <entry key="mail"> <set> <value>primaryEmailAddress</value> </set> </entry> <!-- snip --> </map> </property>
Modify Moodle Source - To include a username in LTI launch params, edit
moodle/mod/lti/locallib.php
ormoodle/mod/basiclti/locallib.php
to add a line like the following to the block where launch parameters are assembled:$requestparams['lis_person_username'] = $USER->username;
E.g. the end result should resemble:
$requestparams['lis_person_name_given'] = $USER->firstname; $requestparams['lis_person_name_family'] = $USER->lastname; $requestparams['lis_person_name_full'] = $USER->firstname." ".$USER->lastname; // Next line added to export the current user's username as a LTI launch param $requestparams['lis_person_username'] = $USER->username;
Similar code changes may be feasible if you need to include a
schoolId
parameter, but the details depend on where/how exactly your Moodle instance stores that value.
OOTB, Moodle also does not necessarily send a LTI launch parameter that maps to SSP section_code
in an obvious way. In some deployments the context_label
launch parameter serves this purpose, but whether or not that field has the necessary semantics is very deployment specific. Some trial and error may be necessary. If no OOTB-supported launch parameters can be correctly mapped to section_code
, a Moodle code patch similar to that proposed above for username
may be necessary.