We are demystifying the Experience API for ourselves and anyone else that wants to follow along. This article will begin applying what has been learned from past exploration. Let's start a project to integrate a LMS and LRS using xAPI.
We have been on a journey to understand the Experience API. We previously explored the following:
- Experience API Terminology
- Launching an Experience API Activity Provider
- Retrieving Experience API Statements from a LRS
- Recording Experience API Statements in a LRS
- Integrating a LMS and Experience API LRS with Basic Auth
- Integrating a LMS and Experience API LRS with OAuth
- Integrating a LMS and Experience API LRS with CMI-5
Our past exploration has uncovered concerns in options for integrating a LMS with a xAPI Activity Provider. The xAPI specification gives options to Activity Providers for securing calls to a LRS. The appropriate options for an Activity Provider depend on their technology.
- Basic Authentication is simple enough for all Activity Providers to implement, but the Launch Link exposes credentials that are not user specific.
- OAuth solves the exposed credential concern by removing the “auth” parameter from the Launch Link, but an Activity Provider needs the ability to keep a secret for OAuth to be securely implemented.
- CMI-5 addresses both concerns by placing additional responsibilities on the LMS and Activity Provider, but the CMI-5 standard is still in development.
We need an interim solution until CMI-5 is released and widely adopted by Activity Providers.
We have identified a few challenges to integration of a LMS and LRS. Let’s establish how to overcome them by identifying requirements, tasks, and level of effort. These will guide us in making decisions about where to focus our time and attention.
Must reliably identify the learner and Activity Provider.
- Implement LTI Tool Provider to verify learner identity with LMS.
- Provide a custom parameter in LTI launch with URL of the Activity Provider.
Must issue unique credentials for each learner session at an Activity Provider.
- Generate unique credentials for every LTI launch.
- Manage issued credentials for later verification.
Must support Activity Providers with limited authentication options.
- Launch Activity Provider with parameters for Basic Authentication.
- Issue unique credentials in “auth” parameter for Basic Auth.
- Assign proxy service in “endpoint” parameter for credential verification.
- Assemble “actor” parameter from LTI parameters.
Must not require learner to have an account on the LRS.
- Validate all request from Activity Provider include issued credentials.
- Substitute issued credentials with LRS credentials.
The tasks are sounding more intimidating than the requirements. The interception of all xAPI requests is a significant effort, and implementing the LTI provider is not something we do often. Let’s see what might already exist to jumpstart this project!
We made an executive decision to use the java platform, so the search for useful tools has been considerably narrowed. Our biggest challenge is the need to proxy request between the Activity Provider and LRS. Next on the list is an LTI Provider authentication library.
Searching the web for “java + http + proxy + servlet” quickly led to a promising project. MITRE’s HTTP-Proxy-Servlet is really simple to deploy and augment. Setup is just defining a target endpoint in the servlet’s configuration, and servlet filters can be used to augment any request and response. This means we can enforce the unique credentials issued to Activity Providers and relay the appropriate credentials to the LRS.
Searching the web for “lti + java + library” was just as fruitful. IMS Global’s basiclti-util-java was exactly what we needed. It turns out that LTI uses an OAuth signature for authentication, but it’s great to find a library from the source of the LTI standard.
Our two biggest obstacles have just been eliminated!
We should begin with a disclaimer of this project being a proof of concept. There is still much work to be done for this to be production ready. That being said, it was a successful proof of concept. The source code is available on Github.
We implemented a SSOServlet that:
- Leverages IMS Global’s basiclti-util-java to act as an LTI provider.
- Generates unique credentials for each learner’s session.
- Stores those credentials in a naive data store.
- Launches the Activity Provider.
We configured a ProxyServlet that:
- Relays request from the Activity Provider to the LRS.
We added an EndpointFilter to the ProxyServlet that:
- Ensures only xAPI request are being relayed to the LRS.
We added an AuthFilter to the ProxyServlet that:
- Verifies credentials on each request from the Activity Provider.
- Modifies the request to have credentials expected by the LRS.
That’s all that was done for this proof of concept. It makes progress towards launching all existing Activity Providers more securely. It still has the major flaw of passing authentication values in the "auth" query string parameter, but that's the only option when Activity Providers only support Basic Authentication. That will change when the "fetch" parameter of CMI-5 becomes widely implemented.
The ease of adding filters to the LRS proxy enables the addition of many useful features. Other additions would also be valuable. We’ll list and categorize some of the possibilities below.
- Implement a robust data store.
- Place a throttle on the proxy to prevent abuse.
- Ensure the actor in all request matches the learner’s session.
- Ensure the “Referer” header in each request matches the domain of the session's activity provider.
- Monitor for “terminated” statements from the Activity Provider to detect completed sessions.
- Implement an endpoint to provide in the “fetch” parameter as an alternative to the “auth” parameter.
- Issue the statements expected of the LMS after LTI succeeds.
- Trigger additional processing based on Activity Provider statements.
- Populate an Operational Data Store with activity trends for analysis.
- Provide learners personal tracking in Google Docs.
The possibilities are really endless. Let your imagination run wild!
We’d love for you to explore the potential of this app further. Feel free to fork the project on Github or spark a discussion in the comments section below. We're currently brainstorming where to take this series next. You can expect more articles as the xAPI and CMI-5 specs evolve. Please mention any topics that interest you in the comments!
Stay tuned! Subscribe to updates by clicking at top of this page!
Also, definitely check out TinCanAPI.com and ADLNet.gov's xAPI standard for more in-depth details. We are just scratching the surface with this whirlwind tour, and those resources were our reference. We would like to give credit and a BIG THANKS to the maintainers of both!