There is a standard called LTI certification. LTI is an acronym for the word Learning Tools Interoperability, which means a standard for exchanging authentication information between learning support tools.
It's a fairly niche technology that has a specific field among authentication technologies, so many people may not know it. Before I specialized in educational technology, I didn't even know the word LTI.
Below is an explanatory diagram of the LTI certification officially issued by IMS GLOBAL.
Personally, I understand that it is a kind of OAuth after all, but the application we develop is Learning Tools, the main tool that is the basis of authentication is Learning Platform, and Learning Tools is an extension of Learning Platform. Instead of providing it, you will get your credentials from the Learning Platform. This has the advantage that users can use various apps properly without switching users. At this time, Learning Tools is also called LTI Tool Provider, and Learning Platform is also called LTI Consumer.
But the question is how to implement this. In fact, because of its niche technology, it lacks documentation, and even if you search on the net, there are not many implementation examples published. So, in this article, I would like to introduce the actual practice of LTI authentication using Ruby on Rails.
First, install the required libraries.
$ bundle add devise
$ bundle add ims-lti
$ bundle add oauth
The advantage of using Rails is that there is a library for lti authentication. This time, we will implement it using ʻims-lti`.
Create a lti_settings.yml
file under config
.
Please describe the following contents (use a safe character string for the consumer key and LTI secret as appropriate).
config/lti_settings.yml
production:
__consumer_key__: '__lti_secret__'
development:
__consumer_key__: '__lti_secret__'
Once created, add the settings to load it to config / application.rb
.
config/application.rb
config.lti_settings = Rails.application.config_for(:lti_settings)
Let's create ltis_controller
and describe the following contents
require 'oauth/request_proxy/action_controller_request'
class LtisController < ApplicationController
skip_before_action :verify_authenticity_token, only: :launch
def lti_launch
#The received consumer key is config/lti_settings.Check if it's in yml
if not Rails.configuration.lti_settings[params[:oauth_consumer_key]]
render :launch_error, status: 401
return
end
shared_secret = Rails.configuration.lti_settings[params[:oauth_consumer_key]]
authenticator = IMS::LTI::Services::MessageAuthenticator.new(request.url, request.request_parameters, shared_secret)
#Check if the signature is valid
if not authenticator.valid_signature?
render :launch_error, status: 401
return
end
#check if the message is too old
if DateTime.strptime(request.request_parameters['oauth_timestamp'],'%s') < 5.minutes.ago
render :launch_error, status: 401
return
end
#Save LTI information in session
session_data = {
"fullname" => authenticator&.message&.lis_person_name_full,
"email" => authenticator&.message&.lis_person_contact_email_primary,
"user_id" => authenticator&.message&.user_id,
"context_id" => authenticator&.message&.context_id,
"context_title" => authenticator&.message&.context_title,
"tool_consumer_instance_name" => authenticator&.message&.tool_consumer_instance_name
}
print(session_data)
session['lti-authenticator'] = session_data
sign_in_and_redirect(User.first)
end
end
You can easily authenticate by passing the request sent to MessageAuthenticator
and the key information held here in advance. If the authentication is successful, the application side authentication is implemented by sign_in using the devise
library.
Finally, let's define the endpoint to launch lti_launch
.
config/routes.rb
match 'lti/launch' => 'ltis#lti_launch', via: [:get, :post], as: :lti_launch
Once this is done, the Learning Platform can write the authentication information described in lti_settings.yml
in advance and set it to transition to the specified endpoint. This method differs depending on the individual Learning Platform, so I will omit it.
Please add the following contents to config / application.rb
config/application.rb
config.lti_settings = Rails.application.config_for(:lti_settings)
config.action_dispatch.default_headers['Referrer-Policy'] = 'unsafe-url'
config.action_controller.forgery_protection_origin_check = false
config.action_controller.allow_forgery_protection = false
Rails LTI Tool Provider IMS LTI
Recommended Posts