BFF + Cookie OIDC : quand Nginx coupe la connexion TLS silencieusement
Contexte
Migration d’une application Blazor WASM depuis une authentification OIDC côté client (oidc-client-ts + JWT Bearer) vers un pattern BFF (Backend For Frontend) : le serveur ASP.NET Core gère le flux OIDC complet, le client reçoit un cookie de session HttpOnly.
La stack :
- Blazor WASM (client) derrière ASP.NET Core (serveur)
- Logto comme fournisseur d’identité (OIDC)
- Nginx en reverse proxy (Jelastic Cloud / Infomaniak)
- Cookie de session
AddCookie()+AddOpenIdConnect()côté serveur
Le symptôme
Après déploiement du BFF, l’authentification passe côté Logto (login OK), mais au retour sur l’application :
Échec de la connexion sécurisée
La connexion avec app.example.com a été interrompue pendant le chargement de la page. La page que vous essayez de consulter ne peut pas être affichée car l’authenticité des données reçues ne peut être vérifiée.
L’erreur apparaît uniquement après authentification. Les pages non authentifiées (/health, pages statiques) fonctionnaient parfaitement avant authentification. Le certificat TLS est valide.
L’investigation
Ce qui fonctionne
- Navigation privée sans authentification : OK
- Endpoint
/health: OK - Certificat SSL : valide (Let’s Encrypt, expire dans 2 mois)
ASPNETCORE_FORWARDEDHEADERS_ENABLED=true: bien configuré
Ce qui ne fonctionne pas
- Toute navigation après que le cookie de session soit émis
- La redirection depuis Logto vers
/signin-oidc
Le coupable : large_client_header_buffers
La configuration Nginx par défaut de Jelastic :
1
2
client_header_buffer_size 1k;
large_client_header_buffers 4 2k;
Le problème saute aux yeux quand on sait que la valeur par défaut de Nginx est 4 8k (documentation officielle). Jelastic a réduit cette valeur à 4 2k dans sa configuration par défaut - quatre fois moins que la valeur standard.
C’est un problème bien connu dans les environnements où Nginx sert de reverse proxy devant des applications avec authentification par cookie. Les JWT tokens seuls peuvent faire 1-2 Ko, et avec les cookies de session OIDC, les state parameters, les tokens CSRF, la taille des headers explose rapidement (source).
Avec le pattern BFF, le cookie de session ASP.NET Core contient :
- Les claims utilisateur chiffrés (sub, email, name, roles)
- Les métadonnées de session (expiration, sliding window)
- Avec
SaveTokens = true: les tokens OIDC (access + id + refresh) - facilement 2-3 Ko de plus
Le cookie chiffré dépasse facilement 2 Ko. Or Nginx est configuré avec des buffers de 2 Ko maximum (au lieu des 8 Ko standard). Quand le navigateur renvoie le cookie sur la requête suivante, Nginx coupe la connexion TLS avant de transmettre au backend. Pas de log d’erreur côté application, pas de code HTTP - juste une connexion TLS interrompue que le navigateur interprète comme une erreur de sécurité.
Habituellement, quand les buffers sont dépassés, Nginx retourne une erreur
400 Bad Request: Request Header or Cookie Too Large. Mais dans notre cas, la connexion TLS est coupée avant que Nginx puisse envoyer une réponse HTTP - d’où le message trompeur d’erreur de sécurité dans le navigateur.
La solution
1. Augmenter les buffers Nginx
Dans nginx-jelastic.conf (section http) :
1
2
3
4
5
# Avant (défaut Jelastic - 4x plus petit que le défaut Nginx !)
large_client_header_buffers 4 2k;
# Après - on restaure le défaut Nginx, suffisant pour les cookies de session OIDC
large_client_header_buffers 4 8k;
Redémarrer Nginx après la modification.
Note :
4 8kest la valeur par défaut de Nginx. Certaines configurations recommandent même4 16kpour les applications avec SSO complexe (DigitalOcean). La mémoire n’est allouée que si les headers dépassent leclient_header_buffer_size(1 Ko), donc l’impact est négligeable.
2. Réduire la taille du cookie
Désactiver SaveTokens si les tokens ne sont pas nécessaires côté serveur après l’authentification :
1
2
3
4
5
.AddOpenIdConnect(options =>
{
// ...
options.SaveTokens = false; // ne pas stocker les tokens dans le cookie
});
Avec le BFF, les tokens ne sont généralement utiles que pendant le flux d’authentification (échange code → tokens → claims). Une fois les claims extraites et stockées dans le cookie de session, les tokens bruts ne servent plus - sauf si on doit appeler des APIs tierces avec l’access token.
Pourquoi ce problème n’existait pas avant
Avec l’authentification JWT Bearer côté client :
- Le token JWT était envoyé dans le header
Authorization: Bearer xxx - Le navigateur n’envoyait aucun cookie d’authentification
- Les headers restaient petits
Avec le BFF + Cookie :
- Le cookie de session est envoyé sur chaque requête same-origin
- La taille des headers augmente significativement
- Les configurations Nginx avec des buffers restrictifs (< 4 Ko) cassent silencieusement
Résumé
| Aspect | Détail |
|---|---|
| Symptôme | Erreur TLS après authentification, pas d’erreur HTTP |
| Cause | large_client_header_buffers Nginx trop petit pour le cookie de session |
| Fix serveur | large_client_header_buffers 4 8k; dans Nginx |
| Fix applicatif | SaveTokens = false pour réduire la taille du cookie |
| Piège | Aucun log côté application - Nginx coupe avant le backend |
Références
- Documentation Nginx -
large_client_header_buffers- valeur par défaut4 8k - Fixing Request Header or Cookie Too Large (DEV Community)
- Resolving 400 Bad Request in Nginx (Stackademic)
- How to Optimize Nginx Configuration (DigitalOcean)
- Kubernetes ingress-nginx - Header Too Large (GitHub) - même problème dans un contexte K8s