RFC 7235 - HTTP/1.1: Autenticazione (Authentication)
- Stato: Proposed Standard
- Pubblicato: June 2014
- Stream: IETF
- Sostituisce: RFC2616, RFC2617
- Sostituito da: RFC9110
- Errata: Nessun errata
Informazioni sul documento
- Numero RFC: 7235
- Titolo: Hypertext Transfer Protocol (HTTP/1.1): Authentication
- Titolo (Italiano): Protocollo di trasferimento ipertesto (HTTP/1.1): Autenticazione
- Data di pubblicazione: Giugno 2014
- Autori: R. Fielding (Adobe), J. Reschke (greenbytes)
- Sostituisce il documento: RFC 2616, RFC 2617 (parzialmente)
- Stato: Standards Track (Percorso degli standard)
Sommario
HTTP fornisce un semplice framework di autenticazione challenge-response, in cui i server possono sfidare le richieste dei client e i client possono fornire informazioni di autenticazione. Questo documento definisce il meccanismo generale del framework di autenticazione HTTP, inclusi i codici di stato 401, 407 e i campi di intestazione correlati.
Concetti fondamentali
Flusso di autenticazione HTTP
1. Il client richiede una risorsa protetta
→ GET /admin HTTP/1.1
2. Il server restituisce una sfida
← HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Admin Area"
3. Il client fornisce le credenziali
→ GET /admin HTTP/1.1
Authorization: Basic dXNlcjpwYXNzd29yZA==
4. Il server verifica e risponde
← HTTP/1.1 200 OK
[Contenuto protetto...]
Schemi di autenticazione (Authentication Schemes)
HTTP supporta diversi schemi di autenticazione:
- Basic: Autenticazione di base (RFC 7617)
- Bearer: Token Bearer (RFC 6750)
- Digest: Autenticazione Digest (RFC 7616)
- OAuth: Autenticazione OAuth (RFC 6749)
401 Unauthorized
Indica che la richiesta non contiene informazioni di autenticazione valide.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="WallyWorld"
Content-Type: text/html
Content-Length: 0
Importante: Il nome "Unauthorized" di 401 significa in realtà Unauthenticated (Non autenticato).
407 Proxy Authentication Required
Indica che il client deve prima autenticarsi presso il proxy.
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="Proxy Access"
Intestazione WWW-Authenticate
Il server utilizza questa intestazione per definire una sfida di autenticazione.
Sintassi di base
WWW-Authenticate: <scheme> realm="<realm>" [, <param>=<value>]*
Esempi
Sfida singola:
WWW-Authenticate: Basic realm="Admin Area"
Sfide multiple (il client può scegliere):
WWW-Authenticate: Bearer realm="API", Basic realm="API"
Con parametri aggiuntivi:
WWW-Authenticate: Digest
realm="[email protected]",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
Parametro realm
realm (dominio) definisce l'ambito dello spazio protetto:
WWW-Authenticate: Basic realm="Area amministratore"
- Solitamente visualizzato nella finestra di dialogo di autenticazione del browser
- Aiuta gli utenti a capire quali credenziali sono necessarie
- Le risorse con lo stesso realm condividono le credenziali
Intestazione Authorization
Il client utilizza questa intestazione per fornire informazioni di autenticazione.
Sintassi di base
Authorization: <scheme> <credentials>
Esempi
Autenticazione Basic:
Authorization: Basic dXNlcjpwYXNzd29yZA==
Token Bearer:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Autenticazione Digest:
Authorization: Digest username="user",
realm="[email protected]",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri="/dir/index.html",
response="6629fae49393a05397450978507c4ef1"
Proxy-Authenticate e Proxy-Authorization
Utilizzati per l'autenticazione proxy, funzionano in modo simile a WWW-Authenticate e Authorization.
Flusso di autenticazione proxy
1. Richiesta del client
→ GET http://example.com/ HTTP/1.1
2. Il proxy richiede l'autenticazione
← HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="Proxy"
3. Il client fornisce le credenziali
→ GET http://example.com/ HTTP/1.1
Proxy-Authorization: Basic cHJveHk6cGFzc3dvcmQ=
4. Il proxy inoltra la richiesta
[Proxy] → GET / HTTP/1.1
Host: example.com
Autenticazione Basic (RFC 7617)
Lo schema di autenticazione più semplice ma meno sicuro.
Codificare le credenziali
// 1. Combinare nome utente e password
const credentials = "username:password";
// 2. Codifica Base64
const encoded = btoa(credentials);
// Risultato: "dXNlcm5hbWU6cGFzc3dvcmQ="
// 3. Costruire l'intestazione Authorization
const auth = `Basic ${encoded}`;
Esempio completo
GET /admin HTTP/1.1
Host: example.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Avviso di sicurezza
Pericolo: L'autenticazione Basic trasmette le credenziali codificate in Base64, non è crittografia!
dXNlcm5hbWU6cGFzc3dvcmQ=
↓ Decodifica Base64
username:password
HTTPS deve essere utilizzato:
✗ http://example.com + Basic Auth = Trasmissione in chiaro
✓ https://example.com + Basic Auth = Trasmissione crittografata
Autenticazione Bearer Token (RFC 6750)
Uno schema di autenticazione comunemente utilizzato per le API Web moderne.
Scenari di utilizzo
Solitamente utilizzato con OAuth 2.0:
1. L'utente accede, ottiene il token di accesso
← { "access_token": "eyJhbG...", "token_type": "Bearer" }
2. Utilizzare il token per accedere all'API
→ GET /api/user HTTP/1.1
Authorization: Bearer eyJhbG...
Esempio
GET /api/resource HTTP/1.1
Host: api.example.com
Authorization: Bearer mF_9.B5f-4.1JqM
Risposta di errore
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="API",
error="invalid_token",
error_description="The access token expired"
Autenticazione Digest (RFC 7616)
Più sicura di Basic, ma più complessa.
Caratteristiche
- Non trasmette direttamente la password
- Utilizza meccanismo challenge-response
- Previene attacchi replay (tramite nonce)
Flusso semplificato
1. Il server invia la sfida (con nonce)
← WWW-Authenticate: Digest realm="...", nonce="..."
2. Il client calcola la risposta
response = MD5(
MD5(username:realm:password) :
nonce :
MD5(method:uri)
)
3. Il client invia la risposta
→ Authorization: Digest username="...", response="..."
Scenari di applicazione pratica
Scenario 1: Login applicazione Web
Modulo tradizionale + Session (consigliato):
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=user&password=pass
→ HTTP/1.1 302 Found
Set-Cookie: sessionid=abc123; HttpOnly; Secure
Non utilizzare HTTP Basic Auth (a meno che non sia tramite HTTPS).
Scenario 2: Autenticazione API
Bearer Token (consigliato):
GET /api/users HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Scenario 3: Protezione interfaccia di amministrazione
Basic Auth + HTTPS (scenari semplici):
GET /admin HTTP/1.1
Host: secure.example.com
Authorization: Basic YWRtaW46c2VjcmV0
Scenario 4: Autenticazione tra microservizi
TLS reciproco + Bearer Token:
GET /internal/service HTTP/1.1
Host: internal.example.com
Authorization: Bearer service-token-123
Autenticazione vs. Autorizzazione
Differenza
Autenticazione (Authentication): "Chi sei?"
Authorization: Bearer [token di identità]
Autorizzazione (Authorization): "Cosa puoi fare?"
Permessi contenuti nel token:
{
"user_id": "123",
"roles": ["admin", "editor"],
"permissions": ["read", "write", "delete"]
}
Codici di stato HTTP
- 401 Unauthorized: Autenticazione fallita o assente
- 403 Forbidden: Autenticazione riuscita, ma senza permesso
L'utente A tenta di accedere a una risorsa amministratore:
→ Non connesso → 401 Unauthorized
→ Connesso (utente normale) → 403 Forbidden
→ Connesso (amministratore) → 200 OK
Migliori pratiche
Lato server
-
Utilizzare sempre HTTPS
✓ https://api.example.com
✗ http://api.example.com -
Fornire realm chiaro
WWW-Authenticate: Bearer realm="My API v1" -
Supportare più schemi di autenticazione
WWW-Authenticate: Bearer realm="API", Basic realm="API" -
Limitare i tentativi falliti
- Implementare la limitazione della frequenza
- Registrare i tentativi di autenticazione falliti
- Considerare il blocco temporaneo dell'account
-
Memorizzare le credenziali in modo sicuro
- Password con hashing forte (bcrypt, Argon2)
- Token con generatore casuale sicuro
Lato client
-
Memorizzare i token in modo sicuro
// ✓ Consigliato
sessionStorage.setItem('token', token);
// ✗ Evitare (rischio XSS)
localStorage.setItem('token', token); -
Gestire le risposte 401
if (response.status === 401) {
// Cancellare il token locale
// Reindirizzare alla pagina di accesso
} -
Aggiornamento del token
// Aggiornare automaticamente il token prima della scadenza
if (tokenExpiresIn < 5 * 60) {
refreshToken();
}
Considerazioni sulla sicurezza
1. Attacchi man-in-the-middle
Rischio: Trasmissione non crittografata delle credenziali
Difesa: Utilizzare HTTPS
✗ HTTP + Basic: Credenziali in chiaro rubate
✓ HTTPS + Basic: Trasmissione crittografata, sicura
2. Attacchi replay
Rischio: Un attaccante intercetta e ritrasmette le richieste di autenticazione
Difesa:
- Utilizzare token a breve termine
- Implementare meccanismo nonce
- Legare il token a un client specifico
3. Perdita di credenziali
Rischio: Le credenziali vengono registrate o divulgate
Difesa:
- Non trasmettere credenziali nell'URL
- Utilizzare token di accesso a breve termine
- Implementare meccanismo di token di aggiornamento
✗ https://api.example.com/data?token=abc123
✓ Authorization: Bearer abc123
4. Attacchi XSS
Rischio: Script dannosi rubano i token
Difesa:
- Utilizzare cookie HttpOnly
- Implementare politiche CSP
- Validare e sanitizzare gli input
Riepilogo
L'autenticazione HTTP fornisce un framework flessibile:
- Fiducia: Implementare con precisione i protocolli di autenticazione, garantire la sicurezza
- Chiarezza: Esprimere chiaramente i requisiti di autenticazione, facilitare l'implementazione lato client
- Eleganza: Progettare elegantemente i flussi di autenticazione, migliorare l'esperienza utente
Principi fondamentali:
- Utilizzare sempre HTTPS
- Scegliere lo schema di autenticazione appropriato per lo scenario
- Implementare una strategia di difesa in profondità
- Ruotare regolarmente le credenziali
Raccomandazioni moderne:
- Applicazioni Web: OAuth 2.0 + OpenID Connect
- API: Bearer Token (JWT)
- Scenari semplici: Basic + HTTPS
- Evitare: Digest (obsoleto e complesso)
Documenti correlati:
- RFC 7617: Autenticazione Basic
- RFC 7616: Autenticazione Digest
- RFC 6750: Bearer Token
- RFC 6749: OAuth 2.0