IMS LTI Outcomes 1.0 Versus 2.0

IMS LTI Outcomes 1.0

First introduced in March 2012 with LTI 1.1, Outcomes-1 has changed little over the years. It finally got its own spec in January 2015, and it’s own name: Learning Tools Interoperability Outcomes Management Service 1.0.

In a nutshell, the Tool Provider can read, write, and delete a decimal score between 0.0 and 1.0 as the result, or outcome, of an LTI launch. The Tool Provider can do this immediately, for example if the tool is a self-scoring game. Or later, for example if the teacher launches the tool later to manually grade an essay submitted in response to the original launch.

IMS LTI Outcomes 2.0

A draft version of Outcomes-2 was introduced in December 2014, but it has not been finalized yet. Outcomes-2 has a similarly long name: Learning Tools Interoperability Outcomes Management Service 2.0.

There are many differences between the specifications (see the table below), but as a product manager, I want to focus on the problems they solve. In this sense, Outcomes-2 is a superset of Outcomes-1: every problem you can solve with Outcomes-1 can also be solved by Outcomes-2. But Outcomes-2 can solve one pervasive problem much better than Outcomes-1.

Comparing Outcomes-1 to Outcomes-2

Outcomes-1 Outcomes-2
LTI compatibility LTI 1.x LTI 1.x and 2.x
Service endpoints One Two
Service methods POST
(data content determines action)
(method determines action in a RESTful way)
Data format XML JSON-LD
Data schemas A single result A single resultAll the results for a single assignment

A single assignment

All the assignments for a class

Result schema Score earned by the learner between 0.0 and 1.0 Score earned by the learner between 0.0 and 1.0The learner that earned the score

Penalty score to be deducted

Extra credit score to be added

Score constraints to be applied

Total score on the assignment

Resulting text score to be displayed

The result status

A comment associated with this result

Assignment schema Not applicable Gradebook labelThe Tool Provider’s activity that produces the associated results

Score constraints to be applied to all associated results

The associated results

What Problems do Outcomes-1 and Outcomes-2 Solve?

Not Enough Time in the Day

Both Outcomes-1 and Outcomes-2 help solve the most common problem teachers want solved: enough time to adjust their teaching to improve student learning. But manually gathering the information they need to adjust their teaching takes a lot of time…time that they are not teaching. Anything that frees up some of their time is a terrific boon. Tool Providers that automatically send information to the teacher are helping that teacher teach and his or her students learn. Even a simple score tells the teacher which students have completed an assignment and if they were able to complete it successfully.

But self-scoring activities and simple scores are not the right fit for all teaching and learning experiences, and that’s were Outcomes-2 starts to shine.

Demonstrating Competence

Teachers often use a style of teaching that asks students to demonstrate their understanding of a concept or their ability to synthesize multiple concepts. There are many ways of demonstrating competence, many of which don’t involve technology at all (such as giving a speech or performing a play). But technology can improve some existing techniques (turning in a document online versus a physically turning in a piece of paper removes the constraints of time and place), and make other techniques possible, such as producing an interactive timeline to demonstrate cause and effect relationships.

One characteristic shared by all demonstrations of competence is the need for an audience, and in particular the teacher. Someone to demonstrate to, and someone to get feedback from. And this is where Outcomes-2 has the advantage.

An Outcomes-2 result has two properties that enable online demonstrations of competence without wasting the teacher’s time and without the constraining either the student or teacher to time and place: the result status and comment. The result status allows the student to tell the teacher where they are in the process: “I’ve started working on assignment” and later, “I’ve completed the assignment”. The result comment can be used to provide more details such as “I’ve finished part 1 of 3”.

Once the result status is “Completed”, the teacher takes over to review the demonstration of competence. Once that review is complete, the teacher can tell the student the final grade and provide simple feedback with the comment (the Tool Provider should provide a mechanism for the teacher to provide detailed feedback if necessary).


Outcomes-2 won’t do anything if it is not built into the learning systems, tools, and content that schools use. Like LTI 2.x, it looks like we are in a stand-off until schools demand that vendors support Outcomes-2. If you are a school trying to implement any kind of online competency based learning, talk to your vendors about how their solution could improve if they implemented Outcomes-2. If you are a vendor with a cool tool that uses Outcomes-2, talk to your schools about how much better your tools would be if their other vendors also supported Outcomes-2.

Posted in Uncategorized | Tagged , , | 3 Comments

LtiLibrary 1.6

So finally, huh!

LtiLibrary (my .NET library for LTI web applications) is now at version 1.6. The big change is the addition Outcomes 2.0 (Draft). Outcomes 2.0 has been in draft status since December 2014. I hope by including support in LtiLibrary, a few people will take up the charge to implement Outcomes 2.0 in production which will help move the spec into final status.

There are two packages on NuGet

You’ll want both if you want Outcomes 2.0. All the source code is on GitHub

Getting Started with Outcomes-2

There are two ApiControllers in LtiLibrary.AspNet that implement the LineItems and LISResult endpoints.

  • LtiLibrary.AspNet.Outcomes.v2.LineItemsControllerBase
  • LtiLibrary.AspNet.Outcomes.v2.ResultsControllerBase

You will need to create your own controllers in your application that inherit from these to handle the actual data. For example,


There are two sample applications in LtiSamples that implement Outcomes-2. SimpleLti is a single page app that hosts both the Tool Consumer and Tool Provider. ConsumerCertification is a simple Tool Consumer that makes all the necessary launch requests to a Tool Provider (yours or someone else’s) to exercise the certification tests.

The biggest advantage I see in Outcomes-2 over Outcomes-1 is that Outcomes-2 supports a comment and a status with each result. In K12, publishers are starting to deliver content catalogs via Thin Common Cartridge where each LTI link points to a single activity such as a lesson or quiz. Let’s say those activities require manual grading. With Outcomes-2, the activity can send a “Completed” result (perhaps with a comment like “Submitted”) to tell the teacher the activity is ready for grading. When the teacher grades the submission, the activity could send a “Final” result (with “Good job!”).

Have fun!

Posted in Uncategorized | Tagged , , , | 4 Comments

LtiLibrary 1.5

LtiLibrary (my .NET library for LTI applications) is now at version 1.5. This coincides with IMS releasing the LTI v1.2 and LTI Outcomes v1.0 Final Specifications,

LtiLibrary 1.5 also supports Content-Item Message v1.0 Public Draft (3 February 2015) and parts of LTI Outcomes Management v2.0 Public Draft (15 December 2015).

LtiLibrary now comes in two parts: LtiLibrary.Core and LtiLibrary.AspNet. Both are available on NuGet,

The source code and samples are available on GitHub,

And the sample Consumer and Provider applications are running on Azure,

If you have any questions or comments about LtiLibrary, please leave them on GitHub.


Posted in Uncategorized | Tagged , , , | Leave a comment

Moving to GitHub

Two years ago I wrote that I was trying both CodePlex and GitHub. For awhile I kept both in sync. But that got tiresome so I let GitHub fall out of sync and focussed on CodePlex. That worked really well while it was just me working on LtiLibrary. CodePlex was my source control system and it integrated very well with Visual Studio.

But recently, I have had code suggestions from folks which they had to carefully format in the CodePlex issues forum. It worked, but it must have been very hard to write. Even more recently, some friends at work convinced me to use Git instead of TFS. That would allow contributors to submit pull requests that I could easily review and merge into master.

So first I converted the LtiSamples project in CodePlex into a Git repository. No problem. Then I wanted to split LtiSamples into two related repositories. Not so simple. I think I would have to create a new project in CodePlex with a new project site (i.e. separate Issues, Documentation, etc). What I really wanted was one “project” with two repositories.

Well that is exactly what GitHub does: LtiLibrary, LtiSamples


So now I’m using Git and the repositories are on GitHub. Wish me luck.

Posted in Uncategorized | Tagged , , , , , | 2 Comments

Splitting LtiLibrary into LtiLibrary.Core and LtiLibrary.AspNet

While I was writing the OWIN middleware for LTI, I noticed that Microsoft and every OWIN middleware contributor created two libraries: one that had no dependencies on ASP.NET and another that did. So I did the same and created LtiLibrary.Owin.Security.Lti (no dependencies on ASP.NET) and LtiLibrary.AspNet.Identity.Owin (dependent on ASP.NET).

That worked out pretty well…so I decided to do the same thing with LtiLibrary. Soon there will be two new packages NuGet to replace LtiLibrary. LtiLibrary.Core is not dependent on ASP.NET, and LtiLibrary.AspNet is dependent on ASP.NET.

Although the LtiLibrary classes, methods, and properties remain the same, the namespace changes, so I will increment the version to 1.5. I’d love feedback on whether I drew the line appropriately…especially while 1.5 has the “-alpha” or “-beta” version suffix.

Posted in Uncategorized | Tagged , , | Leave a comment

Using OWIN to handle LTI API authentication

In my previous post I wrote about the OWIN middleware for LTI I wrote to handle LTI launch authentication. This time I want to talk about using OWIN middleware to authenticate the other LTI stuff: outcomes and the new content-item messages.

The Content Item 1.0 spec piggy backs on top of the LTI launch spec, so authentication works almost exactly the same. The only difference is that I needed to add the OWIN middleware for LTI to the Tool Consumer (e.g. That is because the Tool Provider sends the content placement post to the Tool Consumer (almost as if the Tool Provider were launching something on the Tool Consumer).

However, the application event handlers are much simpler. All I needed to do is ensure the request is valid.


Basic Outcomes are a different story. Because Basic Outcomes are server-to-server messages, it is very easy to implement an ApiController on the receiving end (the Tool Consumer). There is only one external endpoint called Post.


Thanks to Mike Wasson I figured out how to configure the Web API to use OWIN middleware for LTI to authenticate the request in WebApiConfig.cs.


Consumer and Provider have been updated to run with the new code. I had to replace the Provider database and I apologize to everyone that had it configured to work with your Tool Consumer. You will have to re-register your tool consumer.

Posted in Uncategorized | Tagged , , , | Leave a comment

OWIN middleware for LTI


An implementation of  OWIN middleware and ASP.NET Identity for LTI is available on Codeplex.

The Complete Story

Microsoft’s ASP.NET Identity now uses OWIN. Anders Abel has a great series of articles explaining the interaction between OWIN middleware and ASP.NET Identity. In this post, I will dig into my version of OWIN middleware for LTI and how to use it in an ASP.NET MVC application using ASP.NET Identity.

OWIN and One-Legged Authentication

LTI uses one-legged OAuth 1.0 authentication. One-legged refers to fact that the application (i.e. Tool Consumer) is authorized directly by the service provider (i.e. Tool Provider). There is no token exchange or third party authorization service.

All of the OWIN middleware that Microsoft writes (and all of the samples I have found) show three-legged authorizations such as that used by Google and Facebook. My OWIN middleware for LTI implements one-legged authentication.


Let’s look at the AuthenticationHandler first. LtiAuthenticationHandler inherits from the abstract Microsoft.Owin.Security.Infrastructure.AuthenticationHandler and implements AuthenticateCoreAsync() and InvokeAsync(). AuthenticateCoreAsync is never used (it only comes into play with three-legged schemes) and simply returns null.


The real work is done inside InvokeAsync() which is invoked on each request. The first step is to quickly determine if the request is authenticated with LTI.


If it is, the request is parsed into an LtiRequest object and then passed to the application so the application can look up the OAuth secret.


If the LtiRequest signature is valid, then the LtiRequest is passed back to the application again so the application can sign in using an application identity.


That’s really it for the OWIN pipeline. At this point, the request is authenticated and the application can provide the appropriate services (such as display the tool).

Next, let’s look at how the OWIN middleware talks to the application layer as shown above.


All of Microsoft’s OWIN middleware use something called a “Provider” to talk to the application layer. The “Provider” is instantiated when the middleware is created.


LtiAuthenticationProvider supports two events: Authenticate which is invoked just before LtiAuthenticationHandler checks the OAuth signature, Authenticated which is invoked just after. The application can hook into those events and perform any application layer actions required such as looking things up in the application database.


LtiAuthenticationProvider also supports an “event” called GenerateUserName, but this is really used by another application layer method that signs in the user. More on that later.

Everything shown above is in the OWIN middleware for LTI library called LtiLibrary.Owin.Security.Lti. This library is not tied to ASP.NET can can even be used by console apps.

Now let’s look at what goes on in the application layer, namely an MVC Tool Provider.


Startup.Auth.cs is where the MVC app pulls in the appropriate OWIN middleware. When you start a new ASP.NET Web App in Visual Studio, the application will be setup to use Microsoft’s CookieAuthentication OWIN middleware and the main authentication scheme.


To add support for LTI authentication, simply add the LtiAuthentication middleware.


Notice in this example, the OnAuthenticate event is handled by a lamda expression which only recognizes the OAuth key “12345” and returns “secret”. In a real application, you would look up the secret in a database.

OnAuthenticated and OnGenerateUserName use handlers in the SecurityHandler helper class. This is a helper class I wrote to ease the implementation in a typical MVC app. SecurityHandler.OnAuthenticated looks up the matching local user account for the user in the LTI request and signs them in. If a matching account cannot be found, one is created using the username created by SecurityHandler.OnGenerateUserName.

Peek at a Real-ish App

I’ve updated the sample Provider app to use the new OWIN middleware for LTI. As you might expect, the handlers in Startup.Auth.cs are a bit more complex. OnAuthenticate performs an extra security check on the LTI request, and then looks up the OAuth secret in the database.


OnAuthenticated records the LtiRequest in the database, then creates an Outcome if needed to handle future simple outcomes interactions with the Tool Consumer. The IDs of both objects are stored as claims in the application user identity.



Prior to OWIN middleware and Microsoft Identity, it was rather tricky to authenticate LTI requests and connect the external user with a local user. With OWIN middleware, it is easy to integrate with Microsoft Identity and make use of Claims to store LTI information relevant to the application.

Posted in Uncategorized | Tagged , , | 1 Comment