Skip to main content

LTI Authentication and Authorization

Overview

You are responsible for ensuring that requests are signed using your secret. Here is a short list of LTI parameters that you should be validating before signing off on a launch request.

  1. The user is logged in with the same email they are attempting to launch with.
    1. lis_person_contact_email_primary and user_id
  2. The experience being launch (assessment player, item editor, exam builder, etc.) is appropriate for that user
    1. launch_url matches a known list per experience
  3. If an editing experience is being launched, the user has permission to create content in the target workspace
    1. oauth_consumer_key matches the APP_ID you would expect for the user
  4. If the student experience is being launched, they have permission to take the exam being launched
  5. The user role being launched with is appropriate for that user
    1. roles is set to "Learner" or "Instructor" as appropriate.

In practice you will have code that looks something like

// client-side
const service = new window.CampfireSDK.ItemEditor({
// ...
signingFunction:
(launchUrl) => async (params) => {
try {
// this is a web request that return a signature
// for the passed params
const signer = await signCampfireLti(
launchUrl,
params,
);

return {
...params,
oauth_signature: signer.data?.signCampfireLti.signature ?? "",
};
} catch (e) {
console.error(e);
}

return params;
},
})
// server side, in whatever language you use on your server
import { generate } from "oauth-signature";

function mySigningEndpoint(req, current_user) {

// check if user is who they say they are
if (req.params.lis_person_contact_email_primary != current_user.email) {
return { error: "wrong user" }
}

// check if user can launch the requested experience
// launch_experience == "ITEM_EDITOR", etc.
const launch_experience = get_launch_experience(req.params.launchUrl)
if (
!user_can_launch_experience(current_user, launch_experience)
) {
return { error: "user not authorized to launch " + launch_experience }
}

// check if user has appropriate roles
if (user_is_student(current_user)) {
if (req.params.roles !== ["Learner"]) {
return { error: "student is not authorized to launch as teacher" }
}
}

// if the user is launching an exam, they have permission to
// take (if they are a student) or administer (if they are a teacher)
// that exam
if (launch_experience === "ASSESSMENT_PLAYER") {
const examId = getExamIdFromLaunchUrl(params.req.launchUrl);

if ( !user_can_access_exam(current_user, exam_id ) {
return { error: "user cannot access exam" }
}
}

const oauth_signature = generate(
"POST",
req.params.launchUrl,
req.params,
options.secretKey,
undefined,
{ encodeSignature: false }
)

return {
...params,
oauth_signature
}
}

Session Timeout

Launch sessions expire in 8 hours.]