Arquitetura do fluxo LTI 1.3
A Árvore atua como Tool Provider. O LMS é o Platform (issuer do id_token). Toda comunicação inbound do LMS é validada via JWT assinado pelo próprio LMS.
Endpoints públicos da Árvore
| Endpoint | Uso |
|---|---|
https://livros.arvore.com.br/api-arvore/lti/login | OIDC Login Initiation (entry point) |
https://livros.arvore.com.br/api-arvore/lti/launch | Resource Link Launch (recebe id_token) |
https://livros.arvore.com.br/api-arvore/lti/.well-known/jwks.json | JWKS público da Árvore (chaves usadas para assinar requisições NRPS) |
Fluxo passo a passo
1. Iniciação OIDC
Quando o usuário clica na Árvore dentro do LMS, o LMS chama:
GET /api-arvore/lti/login?
iss=https://lms.exemplo.com&
login_hint=user-12345&
target_link_uri=https://livros.arvore.com.br/api-arvore/lti/launch&
client_id=abc123&
lti_deployment_id=1
A Árvore valida o trio (iss, client_id, deployment_id), gera um state assinado e um nonce com TTL de 10 minutos, e redireciona o navegador para o auth_login_url do LMS.
2. Autenticação no LMS
O LMS autentica o usuário (sessão existente, login, etc) e responde com um POST para /lti/launch, contendo id_token (JWT) e state.
3. Validação do id_token
A Árvore valida em sequência:
- Assinatura RS256 contra o JWKS da plataforma (cache de 1h)
isscorresponde ao issuer registradoaudcorresponde aoclient_idregistradoexp/iatdentro da janela aceitávelhttps://purl.imsglobal.org/spec/lti/claim/deployment_idbate com o registrohttps://purl.imsglobal.org/spec/lti/claim/message_typeéLtiResourceLinkRequesthttps://purl.imsglobal.org/spec/lti/claim/versioné1.3.0nonceainda é válido e é consumido atomicamente (proteção contra replay)statefoi assinado pela Árvore e tem TTL válidotarget_link_urido id_token bate com o que veio na iniciação
Falha em qualquer item resulta em 401 Unauthorized.
4. Resolução de usuário e turma (JIT)
Resolvido o id_token, a Árvore:
- Procura uma associação prévia entre
(platform_id, sub)e um usuário Árvore - Se não achar, tenta vincular por
email(claim do id_token) - Se ainda não achar, cria um usuário novo usando
name/given_name/family_name/email - Resolve a turma pelo claim
context.id, criando uma turma nova se for a primeira vez - Garante o perfil correto (aluno ou professor/admin) baseado no claim
roles
5. Sessão Árvore
A Árvore gera um authorization_code OAuth interno e redireciona o navegador para o frontend Árvore com ?code=.... A partir daí o frontend completa o fluxo OAuth padrão para receber access_token + id_token da Árvore.
Diagrama (sequencial)
+--------+ +--------------+ +----------+
| Aluno | | LMS | | Árvore |
+--------+ +--------------+ +----------+
| | |
| clica na Árvore | |
|------------------->| |
| | 1. GET /lti/login |
| |--------------------->|
| | |
| | 2. 302 -> LMS auth |
| |<---------------------|
| | |
| | 3. autentica usuário |
| | |
| | 4. POST /lti/launch |
| | (id_token + state) |
| |--------------------->|
| | |
| | valida JWT, |
| | resolve user, |
| | gera code |
| | |
| | 5. 302 redirect |
| | com ?code=... |
|<------------------------------------------|
| |
| troca code por token (OAuth padrão) |
|------------------------------------------>|
NRPS sync
A Árvore mantém o roster atualizado consultando o LMS periodicamente:
- Para cada turma com
nrps_url, a Árvore monta umclient_assertionJWT (assinado com a chave privada cuja pública está no JWKS público) e troca por umaccess_tokenviaclient_credentials - Faz
GET <nrps_url>comAccept: application/vnd.ims.lti-nrps.v2.membershipcontainer+json - Itera por todas as páginas via header
Link: <url>; rel="next"(se houver) - Atualiza ou cria os usuários e perfis correspondentes na Árvore
Veja NRPS para detalhes do contrato.