| name | dev-oauth2-oidc-advisor |
| description | Implémentation d'OAuth2, OpenID Connect, JWT et gestion des tokens pour sécuriser des APIs et applications web. À utiliser quand l'utilisateur configure de l'authentification, des tokens JWT, ou intègre un identity provider. Se déclenche aussi avec "OAuth2", "OIDC", "OpenID Connect", "JWT", "token", "refresh token", "identity provider", "Keycloak", "Azure AD", "Auth0". |
Conseiller OAuth2 / OIDC
Workflow
- Identifier le flow : Authorization Code, Client Credentials, Device Code, etc.
- Configurer l'IdP : clients, scopes, claims.
- Implémenter : middleware d'authentification, validation de tokens.
- Sécuriser : rotation des secrets, expiration, révocation.
Choisir le bon flow OAuth2
| Flow | Usage | Client |
|---|
| Authorization Code + PKCE | Apps web, SPA, mobile | Public |
| Client Credentials | Service-to-service, APIs | Confidentiel |
| Device Code | IoT, CLI, TV | Public |
| Refresh Token | Renouvellement silencieux | Tous |
Ne plus utiliser
Implicit Flow → remplacé par Authorization Code + PKCE
Resource Owner Password → anti-pattern de sécurité
Implémentation ASP.NET Core
API protégée par JWT
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://auth.company.com";
options.Audience = "payment-api";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromSeconds(30),
ValidIssuers = new[] { "https://auth.company.com" }
};
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("PaymentAdmin", policy =>
policy.RequireClaim("role", "payment-admin"));
options.AddPolicy("ReadPayments", policy =>
policy.RequireClaim("scope", "payments:read"));
});
Client Credentials (service-to-service)
builder.Services.AddHttpClient("PaymentApi", client =>
{
client.BaseAddress = new Uri("https://api.company.com");
})
.AddClientCredentialsTokenHandler(options =>
{
options.Authority = "https://auth.company.com";
options.ClientId = "order-service";
options.ClientSecret = configuration["Auth:ClientSecret"];
options.Scope = "payments:write";
});
Extraction de claims
[Authorize]
[ApiController]
public class PaymentController : ControllerBase
{
[HttpPost]
[Authorize(Policy = "PaymentAdmin")]
public async Task<IActionResult> CreatePayment(CreatePaymentRequest request)
{
var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
var roles = User.FindAll(ClaimTypes.Role).Select(c => c.Value);
var tenantId = User.FindFirst("tenant_id")?.Value;
}
}
Structure d'un JWT
Header.Payload.Signature
{
"alg": "RS256", // Algorithme de signature
"typ": "JWT",
"kid": "key-id-123" // Key ID pour la rotation
}
.
{
"iss": "https://auth.company.com", // Issuer
"sub": "user-123", // Subject (user ID)
"aud": "payment-api", // Audience
"exp": 1700000000, // Expiration
"iat": 1699996400, // Issued at
"scope": "payments:read payments:write",
"role": "payment-admin",
"tenant_id": "tenant-abc"
}
Gestion des tokens
| Token | Durée de vie | Stockage |
|---|
| Access Token | 5-15 minutes | Mémoire (SPA), cookie HttpOnly (web) |
| Refresh Token | 7-30 jours | Cookie HttpOnly secure, rotation obligatoire |
| ID Token | 5-15 minutes | Mémoire, jamais envoyé à une API |
Rotation des refresh tokens
Bonnes pratiques
À faire
- Toujours utiliser HTTPS pour les échanges de tokens
- Valider tous les champs du JWT (issuer, audience, expiration)
- Utiliser des scopes granulaires (
payments:read, payments:write)
- Implémenter la rotation des refresh tokens
- Stocker les tokens côté client dans des cookies HttpOnly Secure SameSite
- Utiliser RS256 (asymétrique) plutôt que HS256 pour les APIs publiques
À éviter
- Stocker des tokens dans le localStorage (vulnérable au XSS)
- Des access tokens de longue durée (> 15 min)
- Mettre des données sensibles dans le payload JWT (pas chiffré)
- Faire confiance au token sans vérifier la signature
- Utiliser le même secret pour tous les environnements
Règles
- Le flow Implicit est obsolète — toujours utiliser Authorization Code + PKCE.
- Les access tokens doivent expirer en moins de 15 minutes.
- Les refresh tokens doivent avoir une rotation activée.
- Valider issuer, audience et signature sur chaque requête.
Communication Rules — MANDATORY
- Ultra-concise. No filler, no preamble, no pleasantries.
- Never say "happy to help", "sure!", "great question", "let me", or similar.
- Tool first, talk second. Act before explaining.
- Result first. Lead with outcome, not process.
- Stop when done. No summary, no recap, no trailing commentary.
- No politeness wrappers. Direct and blunt.
- Minimum words. If one word works, do not use ten.
- No unsolicited explanations.
- No emoji unless asked.