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.
- The user is logged in with the same email they are attempting to launch with.
lis_person_contact_email_primary
anduser_id
- The experience being launch (assessment player, item editor, exam builder, etc.) is appropriate for that user
launch_url
matches a known list per experience
- If an editing experience is being launched, the user has permission to create content in the target workspace
oauth_consumer_key
matches the APP_ID you would expect for the user
- If the student experience is being launched, they have permission to take the exam being launched
- The user role being launched with is appropriate for that user
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.]