浏览代码

README aggiornato

main
父节点
当前提交
5673af6978
共有 1 个文件被更改,包括 47 次插入28 次删除
  1. +47
    -28
      README.md

+ 47
- 28
README.md 查看文件

@@ -46,7 +46,7 @@ npm start
Per un deploy reale del CPC, oltre a far girare il processo Next servono altri tre setup, ciascuno con la sua sezione dedicata:

1. **Apache reverse proxy** che esponga il portale su `https://<host>/cards/` → vedi [Deploy sotto sotto-percorso (basePath) dietro Apache](#deploy-sotto-sotto-percorso-basepath-dietro-apache).
2. **Autenticazione Keycloak** per `/cards/admin` e le API di scrittura → vedi [Protezione dell'amministrazione (Keycloak) e routing](#protezione-dellamministrazione-keycloak-e-routing). In sintesi: serve un **realm role** chiamato **`cpc-admin`** in Keycloak; assegnalo a ogni utente che deve avere accesso all'admin del CPC. Solo gli utenti con questo ruolo possono entrare; tutti gli altri (autenticati o no) vengono reindirizzati alla home pubblica.
2. **Autenticazione Keycloak** per `/cards/admin` e le API di scrittura → vedi [Protezione dell'amministrazione (Keycloak) e routing](#protezione-dellamministrazione-keycloak-e-routing). In sintesi: deve esistere in Keycloak un utente con username **`admin`** (lo username è la chiave di accesso). Per più amministratori si aggiungono altri username alla whitelist nei `<Location>` Apache. Tutti gli altri utenti (autenticati o no) vengono reindirizzati alla home pubblica.
3. **Binari di sistema** (`ffmpeg`, `ffprobe`, `zip`, `unzip`) per upload video / backup → vedi [Prerequisiti di sistema](#prerequisiti-di-sistema).

---
@@ -329,9 +329,9 @@ Punti chiave:
L'autorizzazione **non** è gestita dall'app Next ma da **Apache `mod_auth_openidc`** (Keycloak), già usato dal captive portal. L'app non contiene codice di auth: si fida del gate del reverse proxy.

### Cosa è protetto
- **Pagina `/cards/admin`** e **API di scrittura**: accessibili solo agli utenti Keycloak che appartengono al **realm role `cpc-admin`**. Più amministratori si gestiscono assegnando/rimuovendo il ruolo agli utenti, senza toccare Apache.
- **Non autenticato** su `/cards/admin` → mandato al **login Keycloak**; al ritorno, se ha il ruolo `cpc-admin` entra, altrimenti **redirect alla home** (nessun errore).
- **Autenticato ma senza ruolo `cpc-admin`** → redirect alla home (`403`).
- **Pagina `/cards/admin`** e **API di scrittura**: accessibili solo agli utenti Keycloak il cui `preferred_username` è nella whitelist Apache (di default: `admin`). Per più amministratori si aggiungono altri username, separati da spazi, alla stessa direttiva `Require claim`.
- **Non autenticato** su `/cards/admin` → mandato al **login Keycloak**; al ritorno, se il suo username è in whitelist entra, altrimenti **redirect alla home** (nessun errore).
- **Autenticato ma con username non in whitelist** → redirect alla home (`403`).
- **Restano pubbliche** (servono al portale per tutti gli utenti WiFi): le **GET** di `/cards/api/cards` e `/cards/api/portals`, e `/cards/api/files`, `/cards/api/fonts`.
- Protette su **tutti i metodi**: `/cards/api/upload`, `/cards/api/transcode`, `/cards/api/admin/*` (incluse le GET come backup e stato factory-preset).

@@ -341,9 +341,9 @@ L'autorizzazione **non** è gestita dall'app Next ma da **Apache `mod_auth_openi

1. Apri l'**Admin Console** di Keycloak.
2. Seleziona il realm del captive portal (es. `interceptor1`).
3. **Realm roles** → bottone **Create role** → name: `cpc-admin` → **Save**. (Da fare una sola volta.)
4. Per ogni utente che deve diventare amministratore: **Users** → seleziona l'utente → tab **Role mapping** → **Assign role** → cerca e seleziona `cpc-admin` → **Assign**.
5. *(Verifica opzionale)* **Clients** → `interceptor1-client` (o il nome del tuo client) → tab **Client scopes** → **Evaluate** → scegli un utente con `cpc-admin` → **Generated access token** → controlla che `realm_access.roles` contenga `cpc-admin`.
3. **Users** → verifica che esista un utente con username **`admin`** (o crea l'utente se non c'è: bottone **Add user** → Username: `admin` → **Create** → imposta una password dal tab **Credentials**).
4. Per più amministratori, NON è necessario fare nulla in Keycloak: basta aggiungere altri username alla whitelist Apache (vedi punto B). Crea solo gli utenti Keycloak corrispondenti.
5. *(Verifica opzionale)* **Clients** → `interceptor1-client` → tab **Client scopes** → **Evaluate** → scegli l'utente → **Generated ID token** → controlla che il claim `preferred_username` valga `admin`. Quel claim è incluso di default nei token Keycloak.

#### B — Configurazione Apache (vhost del captive portal)

@@ -378,11 +378,11 @@ Apri il file vhost (quello con i segnaposto `@@@REDIRECT@@@`, `@@@DIRECTORY@@@`,

3. **In ENTRAMBI i vhost** aggiungi i blocchi di protezione **dopo** le `<Location /general/...>` esistenti e **prima** di `OIDCRedirectURI`:
```apache
# Pagina admin: non autenticato → login Keycloak; autenticato senza ruolo → home
# Pagina admin: non autenticato → login Keycloak; autenticato non-admin → home
<Location "/cards/admin">
AuthType openid-connect
OIDCUnAuthAction auth
Require claim realm_access.roles:cpc-admin
Require claim preferred_username:admin
ErrorDocument 403 https://@@@REDIRECT@@@/cards/
</Location>

@@ -391,14 +391,14 @@ Apri il file vhost (quello con i segnaposto `@@@REDIRECT@@@`, `@@@DIRECTORY@@@`,
<LimitExcept GET HEAD>
AuthType openid-connect
OIDCUnAuthAction 401
Require claim realm_access.roles:cpc-admin
Require claim preferred_username:admin
</LimitExcept>
</Location>
<Location "/cards/api/portals">
<LimitExcept GET HEAD>
AuthType openid-connect
OIDCUnAuthAction 401
Require claim realm_access.roles:cpc-admin
Require claim preferred_username:admin
</LimitExcept>
</Location>

@@ -406,17 +406,17 @@ Apri il file vhost (quello con i segnaposto `@@@REDIRECT@@@`, `@@@DIRECTORY@@@`,
<Location "/cards/api/upload">
AuthType openid-connect
OIDCUnAuthAction 401
Require claim realm_access.roles:cpc-admin
Require claim preferred_username:admin
</Location>
<Location "/cards/api/transcode">
AuthType openid-connect
OIDCUnAuthAction 401
Require claim realm_access.roles:cpc-admin
Require claim preferred_username:admin
</Location>
<Location "/cards/api/admin">
AuthType openid-connect
OIDCUnAuthAction 401
Require claim realm_access.roles:cpc-admin
Require claim preferred_username:admin
</Location>
```

@@ -429,30 +429,49 @@ Apri il file vhost (quello con i segnaposto `@@@REDIRECT@@@`, `@@@DIRECTORY@@@`,
#### C — Test (in finestra incognito, sessione pulita)

1. Vai su `https://<host>/cards/admin` da non autenticato → ti porta al login Keycloak.
2. Login con un utente **senza** ruolo `cpc-admin` → ritorni e finisci a `https://<host>/cards/` (home, 403→redirect).
3. Login con un utente **con** ruolo `cpc-admin` → ti entra nell'admin; salvataggi, upload, backup devono funzionare.
2. Login con un utente il cui username NON è in whitelist → ritorni e finisci a `https://<host>/cards/` (home, 403→redirect).
3. Login con l'utente `admin` (o un altro username messo in whitelist) → ti entra nell'admin; salvataggi, upload, backup devono funzionare.
4. `GET https://<host>/cards/api/files?name=...` da non autenticato deve restare pubblico (immagine visibile a tutti gli utenti del captive).

### Note tecniche

- **Pagina admin** usa `OIDCUnAuthAction auth`: il non autenticato viene mandato al login Keycloak. Questo è anche ciò che **riemette il cookie di sessione al path `/`** dopo aver impostato `OIDCCookiePath /`, sanando il classico `401` "anche da autenticato". Solo `ErrorDocument 403` (autenticato senza ruolo → home): **non** usare `ErrorDocument 401`, perché Apache non sa fare un redirect su un `401` (genera l'errore "a 401 error was encountered while trying to use an ErrorDocument").
- **API** usano `OIDCUnAuthAction 401` e **nessun** `ErrorDocument`: un accesso non autorizzato riceve `401/403` (corretto per una chiamata fetch, che non va rediretta). L'admin, già autenticato e con il ruolo `cpc-admin`, invia il cookie di sessione con le richieste e può salvare/caricare/fare backup.
- **Pagina admin** usa `OIDCUnAuthAction auth`: il non autenticato viene mandato al login Keycloak. Questo è anche ciò che **riemette il cookie di sessione al path `/`** dopo aver impostato `OIDCCookiePath /`, sanando il classico `401` "anche da autenticato". Solo `ErrorDocument 403` (autenticato non-admin → home): **non** usare `ErrorDocument 401`, perché Apache non sa fare un redirect su un `401` (genera l'errore "a 401 error was encountered while trying to use an ErrorDocument").
- **API** usano `OIDCUnAuthAction 401` e **nessun** `ErrorDocument`: un accesso non autorizzato riceve `401/403` (corretto per una chiamata fetch, che non va rediretta). L'admin, già autenticato come utente in whitelist, invia il cookie di sessione con le richieste e può salvare/caricare/fare backup.
- Niente VirtualHost dedicato: la protezione sta nello stesso vhost dove l'OIDC è configurato (la sessione è condivisa col captive portal via cookie a path `/`).

### Aggiungere o rimuovere amministratori (dopo il setup iniziale)
### Aggiungere o rimuovere amministratori

Si fa **interamente in Keycloak**, senza toccare Apache o l'app:
L'amministratore è identificato dal **`preferred_username` Keycloak**, controllato nei `<Location>` Apache. Per gestire più amministratori:

- **Aggiungere un admin**: Users → utente → tab **Role mapping** → **Assign role** → `cpc-admin`.
- **Rimuovere un admin**: stessa pagina → rimuovi `cpc-admin` da quell'utente.
1. **In Keycloak** (Admin Console → Users): crea/verifica gli utenti con gli username che vuoi promuovere ad admin (es. `admin`, `alice`, `bob`). Imposta le credenziali normalmente.
2. **In Apache** (in tutti i blocchi `<Location "/cards/admin">`, `<Location "/cards/api/...">`): elenca gli username separati da spazi sulla riga `Require claim`:
```apache
Require claim preferred_username:admin alice bob
```
(I valori multipli sono in OR — passa chiunque abbia uno di quegli username.)
3. **Reload Apache**: `apachectl configtest && systemctl reload apache2`.

L'utente deve fare **logout/login** (o attendere il refresh del token) perché il cambio di ruolo compaia nel claim. La regola Apache resta invariata.
**Rimuovere un admin**: togli lo username dalla riga `Require claim` di Apache (e ricarica), oppure disabilita l'utente in Keycloak.

**Variante rapida senza Keycloak** — se preferisci una whitelist hardcoded di username per pochi utenti fissi, sostituisci la riga `Require claim realm_access.roles:cpc-admin` (in tutti i blocchi) con:
```apache
Require claim preferred_username:admin alice bob
```
(I valori multipli sono in OR.) Ogni modifica richiede di toccare il vhost e ricaricare Apache.
#### Variante avanzata: ruoli Keycloak invece di username

In linea di principio si potrebbe gestire la lista degli amministratori interamente da Keycloak (creando un realm role `cpc-admin` e assegnandolo agli utenti), in modo da non dover toccare Apache ogni volta. Apparentemente basterebbe sostituire la riga con `Require claim realm_access.roles:cpc-admin`.

**Attenzione (limite osservato sul nostro `mod_auth_openidc`):** la dot-notation `realm_access.roles:cpc-admin` punta a un claim **annidato** (un array dentro un oggetto JSON) e la versione installata sui server di produzione **non la valuta correttamente** — il risultato è che la `<Location>` viene di fatto bypassata e chiunque entra in `/cards/admin`. Per usare i ruoli serve quindi un Mapper Keycloak che **appiattisca** il claim:

1. Keycloak → Clients → `interceptor1-client` → tab **Client scopes** → clicca lo scope dedicato del client (es. `interceptor1-client-dedicated`) → tab **Mappers** → **Add mapper** → **By configured type** → **User Realm Role**.
2. Compila: Name=`cpc-roles`, Token Claim Name=`cpc_roles`, Claim JSON Type=`String`, **Multivalued: ON**, **Add to ID token: ON**, **Add to access token: ON**, Realm Role prefix=*(vuoto)*.
3. Save. Crea il ruolo realm `cpc-admin` e assegnalo agli utenti admin.
4. In Apache, in tutti i blocchi, sostituisci la riga `Require claim` con:
```apache
Require claim cpc_roles:cpc-admin
```
(Claim top-level con valore array → matcha qualunque elemento contenga `cpc-admin`.)
5. Reload Apache. Gli utenti devono fare logout/login per ottenere un token con il nuovo claim.

A quel punto, ogni nuovo admin si gestisce solo in Keycloak (assegnando/rimuovendo `cpc-admin`), senza toccare Apache.

**Quale scegliere:** se hai pochi amministratori stabili → resta con `preferred_username`, più semplice e già funzionante. Se ne hai molti o ruotano → vale la pena configurare il Mapper e passare al ruolo.

### Pagine inesistenti → redirect alla home
Qualsiasi percorso non corrispondente a una pagina o API reale del progetto **non mostra una schermata d'errore**: viene reindirizzato alla home. È gestito lato Next da una rotta catch-all ([app/[...not_found]/page.tsx](app/%5B...not_found%5D/page.tsx)) che esegue `redirect('/')`. Le rotte reali (`/`, `/admin`, `/api/*`) hanno priorità; solo i path inesistenti finiscono lì. Le API inesistenti restano `404` (il redirect riguarda le pagine).


正在加载...
取消
保存