Files
ThothII/docs/install/authentication-upstream.md

187 lines
9.7 KiB
Markdown

# Autenticazione tramite portale e proxy fidato
Questa è la modalità **upstream** usata dall'integrazione Omics. Non è il login
OIDC diretto di ThothII: l'utente accede a Omics come già fa, poi sceglie
Datamart Builder e trova ThothII già autenticato. Non deve essere creato un utente
locale ThothII né effettuato un secondo scambio OIDC dall'applicazione embedded.
## Il confine di fiducia
```mermaid
sequenceDiagram
actor U as Utente già autenticato
participant N as Nginx Omics
participant D as Django Omics
participant T as Core ThothII upstream
U->>D: Apri Datamart Builder
D-->>U: Pagina autorizzata con mount React
U->>N: GET /datamart-builder/api/me (cookie Omics)
N->>D: Subrequest interna /datamart-builder/api-auth
D-->>N: 200 + identità verificata, oppure 403
N->>T: GET /me + intestazioni normalizzate (solo se autorizzato)
T-->>U: Identità e permessi applicativi, oppure rifiuto
```
L'header e l'adapter JavaScript non autenticano nessuno. Il backend accetta una
richiesta upstream solo con un'identità valida ricevuta da un percorso di rete
fidato. Gli header non sono firmati da ThothII: la protezione è il proxy che
verifica la sessione e sovrascrive l'identità, insieme all'isolamento del core.
Un core upstream direttamente raggiungibile da client non fidati è una falla,
non una modalità alternativa di accesso.
## Configurazione del core
Per Omics il descrittore pubblico deve contenere:
```yaml
shell:
mode: embedded
defaultLocale: en
adapter: omics-portal
```
Separatamente, il **processo core** deve ricevere `AUTH_MODE=upstream`. Definirlo
nell'override Compose approvato e incluso nell'installazione; una variabile nel
file di interpolazione `.env` non viene passata automaticamente al container:
```yaml
services:
core:
environment:
AUTH_MODE: upstream
```
È solo il frammento di selezione auth, non un file Compose completo né una
configurazione di rete sufficiente. Non aggiunge porte pubbliche.
Condizioni obbligatorie:
1. Nessun `auth.yaml` local/OIDC deve essere effettivamente montato al percorso
letto dal core (default `/run/thothii-auth/auth.yaml`). Se è presente insieme
ad `AUTH_MODE`, l'avvio fallisce. Non impostare `AUTH_MODE=local` o `oidc`:
questi due modi si selezionano dal file, non da quella variabile.
2. Non configurare `authentication.runtimeProjection` per questo percorso: è la
proiezione delle configurazioni cookie local/OIDC, non l'identità Omics.
Nemmeno `THT_AUTH_RUNTIME_PROJECTION_ROOT` deve attivarla nel core.
3. Il descrittore e Compose base continuano a richiedere `authentication.configDirectory`
e `THT_AUTH_CONFIG_ROOT` coerenti. Per una nuova installazione upstream usare
una directory dedicata senza `auth.yaml`, non cancellare la configurazione di
un'installazione esistente. I cambi di modalità richiedono un piano separato.
4. Non esiste `tht auth configure --mode upstream`: il CLI configura gli utenti
locali o l'OIDC diretto. Conservare il percorso proxy già operativo per Omics.
5. `profile: server`, storage delle sessioni e `THOTH_PUBLIC_EXPOSURE` hanno propri
vincoli, che rimangono attivi. La shell embedded non li soddisfa automaticamente.
Il sorgente considera upstream un percorso di compatibilità con il proxy; è
quello usato dall'integrazione Omics corrente. `none` e `mock` sono per sviluppo/test,
non soluzioni a errori di configurazione in produzione.
## Intestazioni richieste all'ingresso del core
| Header | Regola ThothII | Valore Omics |
| --- | --- | --- |
| `X-Thoth-Principal-Issuer` | Stringa stabile, obbligatoria | `portal` |
| `X-Thoth-Principal-Subject` | ID stabile dell'utente, obbligatorio | `str(user.pk)` Django |
| `X-Thoth-Principal-Display-Name` | Facoltativo, se presente non vuoto | Nome completo o username |
| `X-Thoth-Is-Admin` | Obbligatorio: `0`, `1`, `false` o `true` | Risultato di `is_authentik_admin(user)` |
Le stringhe sono ripulite degli spazi esterni, devono avere al massimo 512
caratteri e non contenere caratteri di controllo. Header mancanti o invalidi
producono 401. `false`/`0` assegna il ruolo `user`; `true`/`1` assegna `user` e
`admin`. Il core espande i permessi dal proprio catalogo, non da un array inviato
dal browser. `/me` richiede `session.use`.
La coppia `(issuer, subject)` identifica il proprietario delle sessioni.
Non sostituire il subject con un nome visualizzato o un'email modificabile; non
cambiare issuer/subject di utenti esistenti per correggere un problema grafico.
Passare da identità `portal` a identità OIDC diretta non migra la proprietà dei dati.
## Omics: percorsi e componenti esatti
| Percorso | Destinazione e funzione |
| --- | --- |
| `/kokoro/datamart-builder/` | Pagina Django con `datamart_builder.access` |
| `/datamart-builder/config.js` | Config pubblico del frontend, senza cache |
| `/datamart-builder/assets/…` | Asset frontend risolti dal manifest Vite |
| `/datamart-builder/api/…` | Nginx con `auth_request`, poi core senza il prefisso |
| `/_thothii_auth` | Location Nginx interna, non un login pubblico |
| `/datamart-builder/api-auth` | Django verifica sessione Omics e capability |
Nel repository Omics:
- `kokoro/datamart_catalog_views.py`: `DatamartBuilderView` e
`datamart_builder_api_auth`; la verifica API risponde 200 o 403, anche 403
quando la sessione è assente/scaduta. Non trasforma l'API in una pagina di login.
- `nginx/nginx.conf`: API direttamente a `thothii-core:8787`, config e asset a
`thothii-frontend:8080`; verificare alias e reti Docker effettivi sul server.
- `templates/kokoro/datamart_builder.html`: mount, config e override del prefisso.
- `kokoro/templatetags/vite.py`: manifest da
`http://thothii-frontend:8080/.vite/manifest.json`, cache Django di 30 secondi.
Nginx usa il cookie Omics nella subrequest a Django. Sulle richieste al core
sovrascrive i quattro header con i risultati della verifica e rimuove
`Cookie`, `Authorization` e `X-Authenticated-User`. Nessuna password o token del
portale deve essere copiato nel config pubblico, nello snapshot adapter o in Web Storage.
`GET /datamart-builder/api/me` restituisce l'identità e i permessi; in upstream
`session` e `csrfToken` sono `null`: non viene creata una sessione-cookie ThothII.
## Non confondere i due percorsi proxy
L'esempio generico `deploy/nginx-authenticated-proxy.conf.example` usa **due hop**:
proxy host → frontend Nginx ThothII → core. Sul tratto privato verso il frontend
trasporta `X-Thoth-Trusted-Principal-*` e `X-Thoth-Trusted-Is-Admin`; il frontend
li converte nei quattro header del core e li elimina prima dell'inoltro.
Omics usa invece **Nginx Omics → core direttamente** per le API e invia gli header
normalizzati senza `Trusted`. Non incollare l'esempio a due hop in questa location:
la famiglia di header sbagliata produce 401. In entrambi i casi i valori devono
venire dalla verifica server, mai dagli header del client. Il tratto privato del
percorso generico deve essere inaccessibile ai client non fidati.
## Origine delle richieste e stream
Browser e API devono restare sullo stesso origin. Il frontend accetta `/api` o un
prefisso same-origin come `/datamart-builder/api`, non un URL `http://core:8787`.
In upstream le scritture con `Origin` sono confrontate con protocollo e Host
percepiti dal core; non usano il token CSRF della sessione ThothII local/OIDC.
Le richieste senza Origin hanno il trattamento non-browser: l'autenticazione del
proxy rimane indispensabile anche per esse.
Nel Nginx Omics esaminato il TLS termina a monte e una mappa **esatta** converte
`https://aritmolab.policlinicosandonato.it` in
`http://aritmolab.policlinicosandonato.it` per il confronto interno. Le altre origini
rimangono invariate e devono essere negate quando non coincidono. È una scelta
specifica della topologia corrente, non un modello da estendere con wildcard,
cancellazione di Origin o riscrittura incondizionata. Verificare Host/protocollo
al core e i dinieghi cross-origin nella topologia realmente rilasciata.
La location API disabilita buffering/cache per SSE e mantiene timeout lunghi.
`auth_request` verifica ogni nuova richiesta, ma non interrompe istantaneamente
uno stream già aperto quando il portale revoca l'utente. ThothII ricontrolla `/me`
al ritorno alla pagina e alla riconnessione degli eventi; non promettere revoca
istantanea fra tutte le schede.
## Logout, rientro e diagnosi
In embedded logout e successivo login sono di Omics. ThothII non chiama
`/auth/logout`, non cancella il cookie Django e non apre un suo login.
Il rifiuto 401/403 di `/me` rimuove lo stato protetto e richiede il rientro dal
portale. Un 403 su una singola operazione non equivale al logout dell'applicazione.
| Sintomo | Controllo mirato |
| --- | --- |
| Secondo header | Config servito: deve essere embedded, non full |
| Nessuna UI e errore preferenze | Selettore Omics `data-lang` e `html data-bs-theme` |
| `/me` 401 dal core | Header obbligatori, famiglia Trusted/normalizzata, percorso proxy |
| `/me` 403 dal proxy | Sessione Omics e capability `datamart_builder.access` |
| `/me` funziona ma POST 403 | Distinguere permesso operativo da mismatch Origin/Host/protocollo |
| 502 o asset assenti | Alias/rete Docker e manifest Vite; attesa cache manifest 30 s |
| Avvio core rifiutato | Coesistenza di `auth.yaml` o runtime projection con `AUTH_MODE` |
| Logout full seguito da rientro IdP immediato | Il logout ThothII non è logout globale OIDC |
Non raccogliere cookie, token, segreti o dump completi delle configurazioni nei
report. Registrare codici HTTP, nomi dei percorsi, revisioni e risultati dei test.
Consegna e rilascio: [procedura Omics](../operations/shell-and-localization.md#verifica-prima-del-deploy-server).
Collaudo obbligatorio: [matrice di accettazione](../testing/authentication-manual-acceptance.md).