Árvore Docs Guia

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

EndpointUso
https://livros.arvore.com.br/api-arvore/lti/loginOIDC Login Initiation (entry point)
https://livros.arvore.com.br/api-arvore/lti/launchResource Link Launch (recebe id_token)
https://livros.arvore.com.br/api-arvore/lti/.well-known/jwks.jsonJWKS 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)
  • iss corresponde ao issuer registrado
  • aud corresponde ao client_id registrado
  • exp / iat dentro da janela aceitável
  • https://purl.imsglobal.org/spec/lti/claim/deployment_id bate com o registro
  • https://purl.imsglobal.org/spec/lti/claim/message_type é LtiResourceLinkRequest
  • https://purl.imsglobal.org/spec/lti/claim/version é 1.3.0
  • nonce ainda é válido e é consumido atomicamente (proteção contra replay)
  • state foi assinado pela Árvore e tem TTL válido
  • target_link_uri do 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:

  1. Procura uma associação prévia entre (platform_id, sub) e um usuário Árvore
  2. Se não achar, tenta vincular por email (claim do id_token)
  3. Se ainda não achar, cria um usuário novo usando name/given_name/family_name/email
  4. Resolve a turma pelo claim context.id, criando uma turma nova se for a primeira vez
  5. 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:

  1. Para cada turma com nrps_url, a Árvore monta um client_assertion JWT (assinado com a chave privada cuja pública está no JWKS público) e troca por um access_token via client_credentials
  2. Faz GET <nrps_url> com Accept: application/vnd.ims.lti-nrps.v2.membershipcontainer+json
  3. Itera por todas as páginas via header Link: <url>; rel="next" (se houver)
  4. Atualiza ou cria os usuários e perfis correspondentes na Árvore

Veja NRPS para detalhes do contrato.