-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathauthentification_interactive.html
More file actions
358 lines (348 loc) · 26.1 KB
/
Copy pathauthentification_interactive.html
File metadata and controls
358 lines (348 loc) · 26.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Authentification & SSO — parcours, sessions, fédération</title>
<style>
:root{--bg:#f8fafc;--card:#fff;--border:#e2e8f0;--text:#1e293b;--muted:#64748b;--acc:#3730a3;--acc2:#312e81;--blue600:#2563eb;--green:#16a34a;--red:#dc2626;--orange:#ea580c;--purple:#7c3aed;--grad1:#1e1b4b;--grad2:#312e81}
@media(prefers-color-scheme:dark){:root{--bg:#0d0d0d;--card:#1a1a1a;--border:#2a2a2a;--text:#e2e8f0;--muted:#94a3b8}}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Segoe UI',system-ui,sans-serif;background:var(--bg);color:var(--text);line-height:1.6}
header{background:linear-gradient(135deg,var(--grad1),var(--grad2));padding:2rem 1rem;text-align:center;border-bottom:2px solid var(--acc)}
header h1{font-size:2rem;font-weight:800;color:#fff}
header p{color:#a5b4fc;margin-top:.4rem;font-size:.95rem}
nav{position:sticky;top:0;z-index:100;background:var(--card);border-bottom:1px solid var(--border);padding:.5rem 1rem;display:flex;gap:.5rem;flex-wrap:wrap;justify-content:center}
.tab-btn{padding:.4rem 1rem;border:none;border-radius:999px;cursor:pointer;font-size:.85rem;font-weight:600;background:var(--border);color:var(--muted);transition:all .2s}
.tab-btn.active{background:var(--blue600);color:#fff}
.tab-btn:hover:not(.active){background:var(--acc);color:#fff}
section{display:none;max-width:1100px;margin:0 auto;padding:1.5rem 1rem}
section.active{display:block}
h2{font-size:1.4rem;font-weight:700;margin-bottom:1rem;color:var(--acc)}
h3{font-size:1.1rem;font-weight:600;margin:1.2rem 0 .6rem}
.grid{display:grid;gap:1rem}.g2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}.g3{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.card{background:var(--card);border:1px solid var(--border);border-radius:.75rem;padding:1.2rem}
.card h4{font-size:1rem;font-weight:700;margin-bottom:.5rem;color:var(--acc)}
.codeblk{background:#1e1e2e;color:#cdd6f4;border-radius:.5rem;padding:1rem;font-family:'Cascadia Code','Fira Code',monospace;font-size:.82rem;overflow-x:auto;margin:.5rem 0;line-height:1.7;white-space:pre-wrap}
.c-kw{color:#89b4fa}.c-str{color:#a6e3a1}.c-comment{color:#6c7086;font-style:italic}.c-val{color:#f9e2af}.c-fn{color:#cba6f7}.c-op{color:#94e2d5}
table{width:100%;border-collapse:collapse;font-size:.85rem;margin:.5rem 0}
th{background:var(--acc);color:#fff;padding:.5rem .75rem;text-align:left}
td{padding:.45rem .75rem;border-bottom:1px solid var(--border)}
tr:hover td{background:var(--border)}
.info-box{background:var(--card);border-left:4px solid var(--acc);border-radius:.5rem;padding:.8rem 1rem;margin:.5rem 0}
.info-box.green{border-color:var(--green)}.info-box.red{border-color:var(--red)}.info-box.blue{border-color:var(--blue600)}.info-box.orange{border-color:var(--orange)}.info-box.purple{border-color:var(--purple)}
.badge{display:inline-block;padding:.2rem .6rem;border-radius:999px;font-size:.75rem;font-weight:600;margin:.1rem}
.badge-blue{background:#dbeafe;color:#1d4ed8}.badge-green{background:#dcfce7;color:#15803d}
.badge-red{background:#fee2e2;color:#b91c1c}.badge-yellow{background:#fef3c7;color:#92400e}
.badge-purple{background:#ede9fe;color:#6d28d9}.badge-indigo{background:#e0e7ff;color:#3730a3}
@media(prefers-color-scheme:dark){.badge-blue{background:#1e3a5f;color:#93c5fd}.badge-green{background:#14532d;color:#86efac}.badge-red{background:#450a0a;color:#fca5a5}.badge-yellow{background:#451a03;color:#fcd34d}.badge-purple{background:#2e1065;color:#c4b5fd}.badge-indigo{background:#1e1b4b;color:#a5b4fc}}
.flow{counter-reset:step;margin:.5rem 0}
.step{position:relative;background:var(--card);border:1px solid var(--border);border-left:4px solid var(--acc);border-radius:.5rem;padding:.7rem .8rem .7rem 2.8rem;margin:.45rem 0;font-size:.86rem}
.step::before{counter-increment:step;content:counter(step);position:absolute;left:.6rem;top:.6rem;width:1.6rem;height:1.6rem;background:var(--acc);color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.8rem}
.step strong{color:var(--acc)}
.xlink{color:var(--acc);font-weight:600;text-decoration:none;border-bottom:1px dotted var(--acc)}
.quiz-q{background:var(--card);border:1px solid var(--border);border-radius:.75rem;padding:1.2rem;margin:.8rem 0}
.quiz-q p{font-weight:600;margin-bottom:.7rem}
.quiz-opt{padding:.5rem .8rem;border:1px solid var(--border);border-radius:.4rem;margin:.3rem 0;cursor:pointer;transition:all .2s}
.quiz-opt:hover{border-color:var(--acc);background:rgba(55,48,163,.06)}
.quiz-opt.correct{background:#dcfce7;border-color:var(--green);color:#166534}
.quiz-opt.wrong{background:#fee2e2;border-color:var(--red);color:#991b1b}
@media(prefers-color-scheme:dark){.quiz-opt.correct{background:#14532d;color:#86efac}.quiz-opt.wrong{background:#450a0a;color:#fca5a5}}
#quiz-score{display:none;text-align:center;padding:1.5rem;background:var(--card);border-radius:.75rem;margin-top:1rem;font-size:1.1rem;font-weight:700}
</style>
</head>
<body>
<header>
<h1>Authentification & SSO</h1>
<p>Le processus de bout en bout : parcours de connexion, facteurs, sessions/tokens, fédération & cycle de vie</p>
</header>
<nav>
<button class="tab-btn active" onclick="showTab('overview')">Vue d'ensemble</button>
<button class="tab-btn" onclick="showTab('journey')">Parcours de connexion</button>
<button class="tab-btn" onclick="showTab('sso')">SSO & fédération</button>
<button class="tab-btn" onclick="showTab('factors')">Facteurs & MFA</button>
<button class="tab-btn" onclick="showTab('sessions')">Sessions & tokens</button>
<button class="tab-btn" onclick="showTab('lifecycle')">Cycle de vie & gouvernance</button>
<button class="tab-btn" onclick="showTab('quiz')">Quiz</button>
</nav>
<section id="overview" class="active">
<h2>Vue d'ensemble</h2>
<div class="info-box">
Cette fiche décrit le <strong>processus</strong> d'authentification et le SSO de bout en bout. Pour le détail des <strong>protocoles</strong> (SAML 2.0, OAuth 2.1, OIDC, FIDO2/passkeys, SCIM), voir la fiche <a class="xlink" href="iam_interactive.html">IAM moderne</a>.
</div>
<div class="grid g3">
<div class="card">
<h4>AuthN</h4>
<p style="font-size:.86rem"><strong>Authentification</strong> : prouver <em>qui</em> tu es. On vérifie une identité via un ou plusieurs facteurs.</p>
</div>
<div class="card">
<h4>AuthZ</h4>
<p style="font-size:.86rem"><strong>Autorisation</strong> : décider <em>ce que</em> l'identité a le droit de faire (permissions, rôles, scopes). Vient après l'AuthN.</p>
</div>
<div class="card">
<h4>Accounting</h4>
<p style="font-size:.86rem"><strong>Traçabilité</strong> : journaliser qui a fait quoi et quand (logs, audit). C'est le 3ᵉ « A » du modèle <strong>AAA</strong>.</p>
</div>
</div>
<div class="grid g2" style="margin-top:1rem">
<div class="card">
<h4>Les acteurs</h4>
<table>
<tr><th>Acteur</th><th>Rôle</th></tr>
<tr><td>Sujet / Utilisateur</td><td>L'entité qui veut s'authentifier (humain, service)</td></tr>
<tr><td><strong>IdP</strong> (Identity Provider)</td><td>Vérifie l'identité et émet une preuve (assertion/token)</td></tr>
<tr><td><strong>SP / RP</strong></td><td>Service Provider / Relying Party : l'application qui fait confiance à l'IdP</td></tr>
<tr><td>Annuaire / Directory</td><td>Où vivent les identités (AD, LDAP, Entra ID)</td></tr>
<tr><td>Facteur / Authenticator</td><td>Le moyen de preuve (mot de passe, passkey, OTP…)</td></tr>
</table>
</div>
<div class="card">
<h4>Identité, identifiant, credential</h4>
<ul style="font-size:.85rem;padding-left:1.2rem;line-height:1.85">
<li><strong>Identité</strong> : l'entité (le compte) et ses attributs</li>
<li><strong>Identifiant</strong> : ce qu'on <em>déclare</em> (login, e-mail, UPN) — public</li>
<li><strong>Credential / preuve</strong> : ce qui prouve l'identité (mot de passe, clé privée, biométrie) — secret</li>
<li><strong>Claim</strong> : une affirmation sur l'identité portée par un token (email, groupe, rôle)</li>
</ul>
<div class="info-box blue" style="font-size:.82rem">Déclarer un identifiant ≠ prouver son identité. L'authentification, c'est la <strong>preuve</strong>.</div>
</div>
</div>
</section>
<section id="journey">
<h2>Le parcours de connexion</h2>
<div class="card">
<h4>Les étapes d'une authentification</h4>
<div class="flow">
<div class="step"><strong>Identification</strong> — l'utilisateur déclare son identifiant (ou l'app le redirige vers l'IdP).</div>
<div class="step"><strong>Challenge</strong> — l'IdP demande une preuve : mot de passe, puis facteur supplémentaire (MFA), ou une passkey.</div>
<div class="step"><strong>Vérification</strong> — l'IdP contrôle la preuve contre l'annuaire / le magasin de credentials (hash, clé publique…).</div>
<div class="step"><strong>Décision & risque</strong> — politiques évaluées (MFA requise ? appareil conforme ? localisation ? Conditional Access).</div>
<div class="step"><strong>Émission d'une preuve</strong> — l'IdP délivre un cookie de session et/ou des tokens (assertion SAML, ID/Access token OIDC).</div>
<div class="step"><strong>Session applicative</strong> — l'app établit sa propre session pour l'utilisateur.</div>
<div class="step"><strong>Accès & ré-évaluation</strong> — l'AuthZ décide des droits ; la session peut être ré-évaluée en continu (Zero Trust).</div>
</div>
</div>
<div class="grid g2" style="margin-top:1rem">
<div class="card">
<h4>Authentification locale</h4>
<p style="font-size:.86rem">L'application gère elle-même la vérification (compte + mot de passe stockés côté app, hashés avec Argon2/bcrypt). Simple, mais chaque app duplique la logique, les credentials et le risque.</p>
</div>
<div class="card">
<h4>Authentification fédérée (déléguée)</h4>
<p style="font-size:.86rem">L'app délègue à un <strong>IdP</strong> : redirection, authentification centralisée, retour avec un token signé. L'app ne voit jamais le mot de passe. Base du SSO.</p>
<div class="info-box green" style="font-size:.82rem">Avantages : MFA centralisée, moins de secrets exposés, expérience unifiée, révocation centralisée.</div>
</div>
</div>
</section>
<section id="sso">
<h2>SSO & fédération</h2>
<div class="info-box">
<strong>SSO (Single Sign-On)</strong> : s'authentifier <strong>une fois</strong> auprès de l'IdP, puis accéder à plusieurs applications sans ressaisir ses identifiants, tant que la session IdP est valide.
</div>
<div class="grid g2">
<div class="card">
<h4>Le flux SSO (fédéré)</h4>
<div class="flow">
<div class="step">L'utilisateur ouvre l'app (SP/RP) — pas de session.</div>
<div class="step">Le SP redirige vers l'<strong>IdP</strong> (avec une requête d'authentification).</div>
<div class="step">L'IdP authentifie (ou réutilise sa session SSO existante) + MFA si requise.</div>
<div class="step">L'IdP renvoie une <strong>assertion/token signé</strong> au SP.</div>
<div class="step">Le SP vérifie la signature & les claims, ouvre la session applicative.</div>
</div>
<div class="info-box blue" style="font-size:.82rem">Détail des protocoles (SAML, OIDC, OAuth) dans la fiche <a class="xlink" href="iam_interactive.html">IAM moderne</a>.</div>
</div>
<div class="card">
<h4>Types de SSO</h4>
<table>
<tr><th>Type</th><th>Exemple</th></tr>
<tr><td>Web SSO (même IdP)</td><td>Session cookie sur le domaine de l'IdP</td></tr>
<tr><td>SSO fédéré (cross-domaine)</td><td>SAML / OIDC entre organisations</td></tr>
<tr><td>Enterprise / desktop SSO</td><td>Kerberos/IWA sur le réseau interne</td></tr>
<tr><td>Social login</td><td>« Se connecter avec Google/Microsoft »</td></tr>
</table>
<h4 style="margin-top:.8rem">Chaîne de confiance</h4>
<p style="font-size:.85rem">IdP et SP échangent des <strong>métadonnées</strong> et des <strong>clés de signature</strong>. Le SP fait confiance aux tokens signés par l'IdP ; il valide signature, émetteur (<code>iss</code>), audience (<code>aud</code>) et expiration (<code>exp</code>).</p>
</div>
</div>
<div class="card" style="margin-top:1rem">
<h4>Bénéfices & risques du SSO</h4>
<table>
<tr><th>Bénéfices</th><th>Risques & parades</th></tr>
<tr><td>Moins de mots de passe → moins de réutilisation/fatigue</td><td>L'IdP devient les « clés du royaume » → <strong>MFA forte obligatoire</strong> sur l'IdP</td></tr>
<tr><td>MFA & politiques centralisées</td><td>SPOF/disponibilité → redondance de l'IdP</td></tr>
<tr><td>Onboarding/offboarding simplifiés</td><td>Session IdP volée = accès large → durées courtes, ré-auth step-up</td></tr>
<tr><td>Audit centralisé</td><td>Déconnexion globale (SLO) complexe → voir onglet Sessions</td></tr>
</table>
</div>
</section>
<section id="factors">
<h2>Facteurs & MFA</h2>
<div class="card">
<h4>Les catégories de facteurs</h4>
<table>
<tr><th>Facteur</th><th>Principe</th><th>Exemples</th></tr>
<tr><td><strong>Ce que je sais</strong></td><td>Connaissance</td><td>Mot de passe, PIN, question secrète</td></tr>
<tr><td><strong>Ce que je possède</strong></td><td>Possession</td><td>Téléphone (OTP/push), clé FIDO2, carte à puce</td></tr>
<tr><td><strong>Ce que je suis</strong></td><td>Inhérence (biométrie)</td><td>Empreinte, visage, iris</td></tr>
<tr><td>Contexte (facteur d'appoint)</td><td>Localisation / comportement</td><td>Géo, appareil connu, horaires</td></tr>
</table>
<div class="info-box blue" style="font-size:.82rem"><strong>MFA</strong> = combiner ≥ 2 facteurs de <em>catégories différentes</em>. Deux mots de passe ≠ MFA.</div>
</div>
<div class="grid g2" style="margin-top:1rem">
<div class="card">
<h4>Méthodes MFA, de la plus faible à la plus forte</h4>
<table>
<tr><th>Méthode</th><th>Robustesse</th></tr>
<tr><td>SMS / e-mail OTP</td><td><span class="badge badge-red">Faible</span> SIM swap, interception</td></tr>
<tr><td>TOTP (app authenticator)</td><td><span class="badge badge-yellow">Moyen</span> phishable</td></tr>
<tr><td>Push + number matching</td><td><span class="badge badge-yellow">Moyen+</span> anti « MFA fatigue »</td></tr>
<tr><td>Clé/Passkey FIDO2 / WebAuthn</td><td><span class="badge badge-green">Fort</span> résistant au phishing</td></tr>
</table>
<div class="info-box green" style="font-size:.82rem"><strong>Passkeys / WebAuthn</strong> : la clé est liée à l'origine (domaine) → un site de phishing ne peut pas la réutiliser. C'est le standard recommandé.</div>
</div>
<div class="card">
<h4>Passwordless & authentification adaptative</h4>
<ul style="font-size:.85rem;padding-left:1.2rem;line-height:1.85">
<li><strong>Sans mot de passe</strong> : passkeys, Windows Hello, clés matérielles → plus de secret partagé à voler</li>
<li><strong>Step-up auth</strong> : réauthentifier (ou exiger un facteur fort) pour une action sensible (virement, admin)</li>
<li><strong>Adaptative / basée sur le risque</strong> : le niveau d'exigence dépend du contexte (appareil, IP, géo, <em>impossible travel</em>, réputation)</li>
<li><strong>Conditional Access</strong> : politiques « SI (contexte) ALORS (contrôle) »</li>
</ul>
<div class="info-box blue" style="font-size:.82rem">Approche <a class="xlink" href="zerotrust_interactive.html">Zero Trust</a> : ne jamais faire confiance implicitement, vérifier en continu.</div>
</div>
</div>
</section>
<section id="sessions">
<h2>Sessions & tokens</h2>
<div class="grid g2">
<div class="card">
<h4>Cookie de session vs token</h4>
<table>
<tr><th>Aspect</th><th>Session cookie</th><th>Token (JWT)</th></tr>
<tr><td>État</td><td>Stateful (côté serveur)</td><td>Stateless (auto-porté)</td></tr>
<tr><td>Stockage</td><td>ID opaque dans un cookie</td><td>Claims signés</td></tr>
<tr><td>Révocation</td><td>Facile (suppr. côté serveur)</td><td>Difficile → TTL court + refresh</td></tr>
<tr><td>Scalabilité</td><td>Store partagé nécessaire</td><td>Vérif. par signature, sans store</td></tr>
</table>
</div>
<div class="card">
<h4>Les 3 tokens d'OIDC</h4>
<ul style="font-size:.85rem;padding-left:1.2rem;line-height:1.85">
<li><strong>ID token</strong> : <em>qui</em> est l'utilisateur (claims d'identité, pour l'app)</li>
<li><strong>Access token</strong> : autorise l'appel à une API (scopes) — courte durée</li>
<li><strong>Refresh token</strong> : obtenir de nouveaux access tokens sans se réauthentifier</li>
</ul>
<div class="info-box orange" style="font-size:.82rem">Un JWT n'est <strong>pas chiffré</strong> par défaut : il est signé (intégrité), pas confidentiel. Ne pas y mettre de secret.</div>
</div>
</div>
<div class="card" style="margin-top:1rem">
<h4>Anatomie d'un JWT</h4>
<div class="codeblk"><span class="c-comment"># 3 parties en Base64URL, séparées par des points : header.payload.signature</span>
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 <span class="c-comment"># header</span>
. eyJpc3MiOiJodHRwczovL2lkcC4uLiJ9 <span class="c-comment"># payload (claims)</span>
. SflKxwRJSMeKKF2QT4f... <span class="c-comment"># signature</span>
<span class="c-comment"># payload décodé :</span>
{
<span class="c-str">"iss"</span>: <span class="c-str">"https://idp.example.com"</span>, <span class="c-comment"># émetteur</span>
<span class="c-str">"sub"</span>: <span class="c-str">"user-123"</span>, <span class="c-comment"># sujet (identité)</span>
<span class="c-str">"aud"</span>: <span class="c-str">"app-web"</span>, <span class="c-comment"># audience (destinataire)</span>
<span class="c-str">"exp"</span>: <span class="c-val">1712345678</span>, <span class="c-comment"># expiration</span>
<span class="c-str">"roles"</span>: [<span class="c-str">"reader"</span>, <span class="c-str">"editor"</span>]
}</div>
</div>
<div class="card" style="margin-top:1rem">
<h4>Sessions, déconnexion & attaques</h4>
<div class="grid g2">
<div>
<h3 style="margin-top:0">Deux niveaux de session</h3>
<p style="font-size:.85rem">La <strong>session SSO chez l'IdP</strong> ≠ la <strong>session applicative</strong>. Se déconnecter d'une app ne détruit pas la session IdP → <strong>Single Logout (SLO)</strong> est nécessaire (et complexe) pour tout fermer.</p>
</div>
<div>
<h3 style="margin-top:0">Menaces & parades</h3>
<ul style="font-size:.84rem;padding-left:1.1rem;line-height:1.7">
<li>Vol de session / token (XSS) → cookies <code>HttpOnly</code>, <code>Secure</code>, <code>SameSite</code></li>
<li>Fixation de session → régénérer l'ID après login</li>
<li>CSRF → anti-CSRF token, <code>SameSite</code></li>
<li>Rejeu de token → TTL court, rotation, binding (DPoP/mTLS)</li>
</ul>
</div>
</div>
</div>
</section>
<section id="lifecycle">
<h2>Cycle de vie de l'identité & gouvernance</h2>
<div class="grid g2">
<div class="card">
<h4>Cycle de vie — JML</h4>
<table>
<tr><th>Phase</th><th>Actions</th></tr>
<tr><td><strong>Joiner</strong></td><td>Création du compte, provisioning, droits initiaux (least privilege)</td></tr>
<tr><td><strong>Mover</strong></td><td>Changement de rôle/service → recalcul des accès</td></tr>
<tr><td><strong>Leaver</strong></td><td>Désactivation immédiate, révocation sessions/tokens, deprovisioning</td></tr>
</table>
<div class="info-box blue" style="font-size:.82rem">Le provisioning automatisé se fait souvent via <strong>SCIM</strong> (voir fiche <a class="xlink" href="iam_interactive.html">IAM</a>). Un <em>leaver</em> non traité = compte orphelin = risque.</div>
</div>
<div class="card">
<h4>Annuaires & sources d'identité</h4>
<ul style="font-size:.85rem;padding-left:1.2rem;line-height:1.85">
<li><strong>On-prem</strong> : Active Directory (Kerberos/NTLM, LDAP)</li>
<li><strong>Cloud</strong> : Entra ID, Okta, Google Workspace</li>
<li><strong>Hybride</strong> : synchronisation (Entra Connect), PHS/PTA/AD FS</li>
</ul>
<p style="font-size:.85rem;margin-top:.4rem">L'IdP s'appuie sur ces annuaires comme source de vérité des identités et des groupes.</p>
</div>
</div>
<div class="grid g2" style="margin-top:1rem">
<div class="card">
<h4>AuthZ — modèles d'autorisation</h4>
<table>
<tr><th>Modèle</th><th>Décision basée sur…</th></tr>
<tr><td><strong>RBAC</strong></td><td>Les rôles attribués à l'utilisateur</td></tr>
<tr><td><strong>ABAC</strong></td><td>Des attributs (utilisateur, ressource, contexte)</td></tr>
<tr><td><strong>PBAC / ReBAC</strong></td><td>Des politiques / relations (ex. propriétaire de la ressource)</td></tr>
</table>
<div class="info-box green" style="font-size:.82rem">Principe transverse : <strong>moindre privilège</strong> — n'accorder que le strict nécessaire.</div>
</div>
<div class="card">
<h4>Bonnes pratiques & pièges</h4>
<ul style="font-size:.85rem;padding-left:1.2rem;line-height:1.8">
<li><strong>MFA partout</strong>, viser le <strong>passwordless</strong> (passkeys)</li>
<li>Désactiver l'<strong>authentification legacy</strong> (protocoles sans MFA)</li>
<li>Sessions à durée limitée + réauthentification step-up</li>
<li>Comptes admin séparés, break-glass, revue régulière des accès</li>
<li>Journaliser & détecter les anomalies (impossible travel, password spray)</li>
<li>Ne jamais rouler sa propre crypto de mots de passe → Argon2id/bcrypt</li>
</ul>
</div>
</div>
</section>
<section id="quiz">
<h2>Quiz — Authentification & SSO</h2>
<div id="quiz-container"></div>
<div id="quiz-score"></div>
</section>
<script>
function showTab(id){document.querySelectorAll('section').forEach(s=>s.classList.remove('active'));document.querySelectorAll('.tab-btn').forEach(b=>b.classList.remove('active'));document.getElementById(id).classList.add('active');event.target.classList.add('active')}
const quizData=[
{q:"Quelle est la différence entre authentification (AuthN) et autorisation (AuthZ) ?",opts:["Aucune, ce sont des synonymes","AuthN prouve qui on est, AuthZ décide ce qu'on a le droit de faire","AuthN concerne les API, AuthZ le web","AuthZ vient avant AuthN"],a:1},
{q:"Dans une authentification fédérée, qui vérifie l'identité et émet la preuve ?",opts:["L'application (SP/RP)","L'Identity Provider (IdP)","Le navigateur","Le pare-feu"],a:1},
{q:"Qu'est-ce que le SSO (Single Sign-On) ?",opts:["Un seul mot de passe pour tout, stocké en clair","S'authentifier une fois auprès de l'IdP puis accéder à plusieurs apps","Un gestionnaire de mots de passe","Un protocole de chiffrement"],a:1},
{q:"Qu'est-ce qui constitue réellement de la MFA ?",opts:["Deux mots de passe","Un mot de passe long","≥ 2 facteurs de catégories différentes (savoir/possession/inhérence)","Un CAPTCHA + mot de passe"],a:2},
{q:"Quelle méthode MFA est résistante au phishing ?",opts:["SMS OTP","TOTP","Passkey / FIDO2 (WebAuthn)","Question secrète"],a:2},
{q:"Pourquoi le SMS OTP est-il considéré comme faible ?",opts:["Trop lent","Vulnérable au SIM swap et à l'interception","Trop cher","Incompatible mobile"],a:1},
{q:"Quel token OIDC sert à identifier l'utilisateur auprès de l'application ?",opts:["Access token","Refresh token","ID token","Session token"],a:2},
{q:"Un JWT est par défaut…",opts:["Chiffré et confidentiel","Signé (intégrité) mais lisible, non confidentiel","Compressé","Stocké côté serveur"],a:1},
{q:"Pourquoi les access tokens (JWT) ont-ils une courte durée de vie ?",opts:["Pour économiser la bande passante","Parce qu'ils sont difficiles à révoquer une fois émis","Par obligation légale","Pour être plus lisibles"],a:1},
{q:"Quel attribut de cookie limite l'envoi cross-site (anti-CSRF) ?",opts:["HttpOnly","Secure","SameSite","Domain"],a:2},
{q:"Dans le cycle de vie JML, que doit-on faire pour un « Leaver » ?",opts:["Rien","Désactiver le compte et révoquer sessions/tokens immédiatement","Augmenter ses droits","Créer un nouveau compte"],a:1},
{q:"Quel modèle d'autorisation décide selon des attributs (utilisateur, ressource, contexte) ?",opts:["RBAC","ABAC","SSO","MFA"],a:1},
{q:"Pourquoi la MFA sur l'IdP est-elle critique en SSO ?",opts:["Pour la vitesse","Parce que compromettre l'IdP donne accès à toutes les apps fédérées","C'est optionnel","Pour le SEO"],a:1},
{q:"Qu'est-ce que l'authentification step-up ?",opts:["Augmenter la longueur du mot de passe","Exiger une preuve plus forte pour une action sensible","Se déconnecter automatiquement","Changer d'IdP"],a:1}
];
let answers=new Array(quizData.length).fill(null);
function buildQuiz(){const c=document.getElementById('quiz-container');c.innerHTML=quizData.map((q,i)=>`<div class="quiz-q"><p>${i+1}. ${q.q}</p>${q.opts.map((o,j)=>`<div class="quiz-opt" onclick="answer(this,${i},${j})">${o}</div>`).join('')}</div>`).join('')}
function answer(el,qi,oi){const parent=el.parentElement;if(parent.querySelector('.correct,.wrong'))return;answers[qi]=oi;const correct=quizData[qi].a;parent.querySelectorAll('.quiz-opt').forEach((o,j)=>{if(j===correct)o.classList.add('correct');else if(j===oi&&oi!==correct)o.classList.add('wrong')});if(answers.every(a=>a!==null)){const score=answers.filter((a,i)=>a===quizData[i].a).length;const sc=document.getElementById('quiz-score');sc.style.display='block';sc.innerHTML=`Score : ${score}/${quizData.length} ${score>=12?'Excellent !':score>=9?'Bien !':'À revoir'}`}}
buildQuiz();
</script>
</body>
</html>