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. http://consumer.azurewebsites.net). 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.

image

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.

image

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.

image

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

TL;DR

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.

LtiAuthenticationHander

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.

image

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.

image

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.

image

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.

image

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.

LtiAuthenticationProvider

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.

image

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.

image

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

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.

image

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

image

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.

image

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.

image

Summary

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

LtiLibrary 1.4 on NuGet

LtiLibrary 1.4.2 is now available on NuGet and there is a sample to go with it. The big changes from version 1.3.3 are support for LTI 1.2 Public Draft and LTI Content-Item Message 1.0 Public Draft. You can get both draft specifications from IMS. LtiLibrary release notes are on CodePlex along with all the source code.

The Consumer and Provider websites have been updated to use LtiLibrary 1.4 (and to use the new Microsoft Identity framework so your old username is probably gone). To play around with the Content-Item Message, try this:

  1. Login to Consumer. Make sure you are a teacher.
  2. Create a Course.
  3. In the Course Details view, open the Assignments section and click on Sample Provider Library to launch a content selector running on Provider.
  4. Decide which tool you want to insert into your course, and click on Assign. This will insert the tool into your course.

You may notice that Content-Item Message 1.0 is designed as a browser-to-browser message. When the Content-Item Message handler sends the selection back to the Tool Consumer, the browser is redirected to the Tool Consumer and the Content-Item Message handler state is lost. This makes it different than the server-to-server messaging of LTI Outcomes and Tool Consumer Profile and I’m not sure how I feel about that.

The use cases imagine involve selecting multiple things and sending them back to the Tool Consumer. The process of selecting multiple things might take several complicated steps (such as a search with several filters applied). But as soon as the Content-Item Message handler sends the first selection back to the Tool Consumer, the search results would be lost. This can be overcome by making the Content-Item Message handler capable of assembling several items before sending them back to the Tool Consumer, but it seems like it would be easier to let the Content-Item Message handler send intermediate results back to the Tool Consumer via server-to-server messages with the final “I’m Done” message browser-to-browser.

What do you think?

Provider is also using the new MVC template based on Bootstrap. Consumer is still using the old template based on jQuery UI. After going through the conversion, I found it takes about the same amount of effort to create new views on either. But I suspect Provider will run on mobile devices with less fiddling.

As I mentioned above, both Provider and Consumer are using the new Microsoft Identify framework. Converting from Simple Membership to Identity was pretty straightforward, though tedious. I was surprised how often I was using identity features that are no longer supported or supported in a different way. The only significant change was in the LtiAuthorizeAttribute.OnAuthorization override which no longer adds the signed in user to the authorization cookie. Instead I simply redirect to the destination page and let the Identify framework do the dirty work. This results in one more browser request, but otherwise is quite transparent. [This is also why the browser back button will generate a “you’ve already used that Nonce” message after an LTI launch. I’ll work on that later.]

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

LTI Talks Back with Content Item Message

Here’s a common use case…a teacher finds something online she wants all her kids to use in the classroom. So she copies the URL and pastes it into her learning system (LMS, Google Docs, whatever). This is so common, it adds up to a lot of work (tens of thousands of teachers pasting hundreds of URLs).

I don’t know if this wass the use case the folks at IMS had in mind when they wrote the new Content Item Message spec, but they could have. The new spec works like this:

  1. A teacher launches a “ContentItemSelection” tool from her learning system.
  2. Using the tool, she finds something she wants all her kids to use in the classroom and clicks on it.
  3. The ContentItemSelection tool sends the URL—and everything needed to LTI Launch the resource—back to their learning system.

That’s it. Done. No copy and paste. No “Create Link” forms to fill in. No strange codes to look up.

When she, or any of her kids, launches the resource; all the relevant LTI information is sent along so resource acts appropriately. For example, it may appear in “teacher mode” when teacher launches the resource, but in “game mode” when students launch it.

I have a simple example running on http://consumer.azurewebsites.net that you are welcome to play with. Here’s a short movie showing how easy it is http://screencast.com/t/HsTdm06V2l6I. Don’t blink or you’ll miss it.

Source code for my sample websites can be found at http://ltisamples.codeplex.com.

Posted in Uncategorized | Tagged , | Leave a comment

Sample LTI Provider 1.3

It took a while, but I finally updated the sample Provider website to version 1.3. The source code is here. Like the sample Consumer, the Provider project is now complete. Previous versions were missing files because I did not want to share my passwords to things like the Twitter API. But that made it hard for people to get started. So…I removed the passwords from the files. Some of the other changes:

  • Replaced SimpleMembership with Microsoft ASP.NET Identity 1.0.
  • Removed 3rd party signin support (so I could include all the project files without sharing my credentials).
  • Replaced most LTI code with LtiLibrary.
  • Converted to bootstrap (previous versions used jQuery UI).

I apologize to everyone that added Consumers or Tools to the sample provider site. Because the conversion to ASP.NET Identity changed so many tables, I gave up trying to migrate and wiped out the database.

Have fun!

Posted in Uncategorized | Tagged , , | Leave a comment

Sample LTI Consumer 1.3

I just updated the sample Consumer website to version 1.3. The source code is here. The biggest change is that the Consumer project is now complete. Previous versions were missing files because I did not want to share my passwords to things like the Twitter API. But that made it hard for people to get started. So…I removed the passwords from the files. Some of the other changes:

Despite all these changes, the website itself looks and acts pretty much like it did before.

Have fun!

Posted in Uncategorized | Tagged | 3 Comments