{
    "componentChunkName": "component---src-templates-plugin-docs-tsx",
    "path": "/plugins/scm-oauth2-plugin/docs/1.0.x/PROZESS_BESCHREIBUNG/",
    "result": {"data":{"plugin":{"name":"scm-oauth2-plugin","displayName":"OAuth2/OIDC","description":"Authentication for SCM-Manager using OAuth2/OIDC","author":"Thorsten Ludewig","documentation":[{"version":"1.0.x","languages":["DATENSCHUTZ_FOLGEABSCHAETZUNG","PROZESS_BESCHREIBUNG","COMPLIANCE_BERICHT","SOURCECODE_STATISTIK","javadoc"]}]},"navigation":{"nodes":[]},"versions":{"group":[{"fieldValue":"1.0.x"}]},"languages":{"group":[{"fieldValue":"COMPLIANCE_BERICHT"},{"fieldValue":"DATENSCHUTZ_FOLGEABSCHAETZUNG"},{"fieldValue":"PROZESS_BESCHREIBUNG"},{"fieldValue":"SOURCECODE_STATISTIK"},{"fieldValue":"javadoc"}]},"markdownRemark":{"html":"<h1 id=\"prozessbeschreibung--scm-oauth2-plugin\" style=\"position:relative;\"><a href=\"#prozessbeschreibung--scm-oauth2-plugin\" aria-label=\"prozessbeschreibung  scm oauth2 plugin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prozessbeschreibung — scm-oauth2-plugin</h1>\n<p><strong>Dokumentversion:</strong> 1.1 · <strong>Stand:</strong> 17.08.2026 · <strong>Softwarestand:</strong> scm-oauth2-plugin 1.0.2</p>\n<p>Technische Beschreibung der Verarbeitungsvorgänge des Plugins als Grundlage für das Verzeichnis von\nVerarbeitungstätigkeiten (Art. 30 DSGVO), für die Risikoanalyse nach Art. 21 Abs. 2 NIS2 und für die\n<a href=\"/2b8b96ac9620994e713b5a4607d53444/DATENSCHUTZ_FOLGEABSCHAETZUNG.md\">Datenschutz-Folgenabschätzung</a>.</p>\n<blockquote>\n<p><strong>Hinweis zur Verwendung:</strong> Dieses Dokument beschreibt ausschließlich das Verhalten der Software.\nAlle organisatorischen Festlegungen (Rechtsgrundlage, Löschfristen, Verantwortlichkeiten,\nAuftragsverarbeitung, Mitbestimmung) trifft der Verantwortliche für seine Instanz. Es handelt sich\nnicht um Rechtsberatung.</p>\n</blockquote>\n<h2 id=\"inhalt\" style=\"position:relative;\"><a href=\"#inhalt\" aria-label=\"inhalt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Inhalt</h2>\n<ol>\n<li><a href=\"#1-rollen-und-abgrenzung\">Rollen und Abgrenzung</a></li>\n<li><a href=\"#2-zweck-der-verarbeitung\">Zweck der Verarbeitung</a></li>\n<li><a href=\"#3-datenkategorien\">Datenkategorien</a></li>\n<li><a href=\"#4-prozess-1--anmeldung-authorization-code-flow\">Prozess 1 — Anmeldung (Authorization Code Flow)</a></li>\n<li><a href=\"#5-prozess-2--benutzerbereitstellung-und-migration\">Prozess 2 — Benutzerbereitstellung und Migration</a></li>\n<li><a href=\"#6-prozess-3--gruppen--und-berechtigungssynchronisation\">Prozess 3 — Gruppen- und Berechtigungssynchronisation</a></li>\n<li><a href=\"#7-prozess-4--autorisierung-im-laufenden-betrieb\">Prozess 4 — Autorisierung im laufenden Betrieb</a></li>\n<li><a href=\"#8-prozess-5--abmeldung-rp-initiated-logout\">Prozess 5 — Abmeldung (RP-initiated Logout)</a></li>\n<li><a href=\"#9-prozess-6--administration-der-konfiguration\">Prozess 6 — Administration der Konfiguration</a></li>\n<li><a href=\"#10-speicherorte-und-speicherdauer\">Speicherorte und Speicherdauer</a></li>\n<li><a href=\"#11-protokollierung\">Protokollierung</a></li>\n<li><a href=\"#12-empf%C3%A4nger-und-datenfl%C3%BCsse-nach-au%C3%9Fen\">Empfänger und Datenflüsse nach außen</a></li>\n<li><a href=\"#13-schnittstellen\">Schnittstellen</a></li>\n</ol>\n<h2 id=\"1-rollen-und-abgrenzung\" style=\"position:relative;\"><a href=\"#1-rollen-und-abgrenzung\" aria-label=\"1 rollen und abgrenzung permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. Rollen und Abgrenzung</h2>\n<table>\n<thead>\n<tr>\n<th>Rolle</th>\n<th>Zuordnung</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Verantwortlicher (Art. 4 Nr. 7 DSGVO)</td>\n<td>Betreiber der SCM-Manager-Instanz</td>\n</tr>\n<tr>\n<td>Weiterer Verantwortlicher</td>\n<td>Betreiber des Identity Providers (IdP), sofern organisatorisch getrennt</td>\n</tr>\n<tr>\n<td>Auftragsverarbeiter</td>\n<td><strong>keiner durch das Plugin</strong> — die Software wird lokal betrieben, es findet kein Datenfluss zum Autor oder zu Dritten statt</td>\n</tr>\n<tr>\n<td>Datenquelle</td>\n<td>IdP (OAuth2/OIDC), mittelbar das dahinterliegende Verzeichnis (z. B. LDAP/AD)</td>\n</tr>\n</tbody>\n</table>\n<p>Das Plugin ist eine lokal installierte Softwarekomponente (<code class=\"language-text\">.smp</code>-Paket, 96 KB) innerhalb des\nSCM-Manager-Prozesses. Es betreibt keinen eigenen Dienst, öffnet keine ausgehenden Verbindungen\naußer zu den konfigurierten IdP-Endpunkten und enthält keine Telemetrie.</p>\n<p><strong>Abgrenzung zum SCM-Manager-Kern:</strong> Benutzerkonten, Gruppen, Berechtigungen, Sitzungs-Cookies und\ndas Logging werden vom Kern verwaltet und persistiert. Das Plugin ruft dessen Schnittstellen auf\n(<code class=\"language-text\">UserManager</code>, <code class=\"language-text\">GroupManager</code>, <code class=\"language-text\">SecuritySystem</code>, <code class=\"language-text\">SyncingRealmHelper</code>, <code class=\"language-text\">AccessTokenCookieIssuer</code>).\nEigene Datenhaltung des Plugins: die Datei je Benutzer unter <code class=\"language-text\">var/data/oauth2Groups/</code> sowie zwei\nflüchtige Speicher im Arbeitsspeicher (siehe <a href=\"#10-speicherorte-und-speicherdauer\">Abschnitt 10</a>).</p>\n<h2 id=\"2-zweck-der-verarbeitung\" style=\"position:relative;\"><a href=\"#2-zweck-der-verarbeitung\" aria-label=\"2 zweck der verarbeitung permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Zweck der Verarbeitung</h2>\n<table>\n<thead>\n<tr>\n<th>Zweck</th>\n<th>Verarbeitungsschritte</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Authentifizierung von Benutzern an SCM-Manager über einen zentralen IdP (Single Sign-on)</td>\n<td>Prozess 1</td>\n</tr>\n<tr>\n<td>Bereitstellung und Aktualisierung des lokalen Benutzerkontos</td>\n<td>Prozess 2</td>\n</tr>\n<tr>\n<td>Zugriffssteuerung anhand der im IdP gepflegten Gruppen und Rollen</td>\n<td>Prozesse 3 und 4</td>\n</tr>\n<tr>\n<td>Beendigung der Sitzung, optional auch der IdP-Sitzung</td>\n<td>Prozess 5</td>\n</tr>\n<tr>\n<td>Betrieb und Administration der Kopplung</td>\n<td>Prozess 6</td>\n</tr>\n</tbody>\n</table>\n<p>Es findet <strong>kein Profiling</strong> und keine Verhaltens- oder Leistungsbewertung statt. Die einzige\nautomatisierte Entscheidung ist die Zuweisung bzw. der Entzug von Zugriffsrechten anhand der\nGruppenzugehörigkeit (siehe <a href=\"/2b8b96ac9620994e713b5a4607d53444/DATENSCHUTZ_FOLGEABSCHAETZUNG.md\">DSFA, Abschnitt zu Art. 22</a>).</p>\n<h2 id=\"3-datenkategorien\" style=\"position:relative;\"><a href=\"#3-datenkategorien\" aria-label=\"3 datenkategorien permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Datenkategorien</h2>\n<p>Welche Claims gelesen werden, ist konfigurierbar; die Spalte „Standard\" nennt die Vorbelegung.</p>\n<table>\n<thead>\n<tr>\n<th>Nr.</th>\n<th>Datum</th>\n<th>Quelle (Claim)</th>\n<th>Standard</th>\n<th>Personenbezug</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>D1</td>\n<td>Benutzerkennung</td>\n<td><code class=\"language-text\">usernameAttribute</code>, ersatzweise <code class=\"language-text\">sub</code></td>\n<td><code class=\"language-text\">preferred_username</code></td>\n<td>ja, identifizierend</td>\n</tr>\n<tr>\n<td>D2</td>\n<td>Anzeigename</td>\n<td><code class=\"language-text\">displayNameAttribute</code></td>\n<td><code class=\"language-text\">name</code></td>\n<td>ja, identifizierend</td>\n</tr>\n<tr>\n<td>D3</td>\n<td>E-Mail-Adresse</td>\n<td><code class=\"language-text\">mailAttribute</code></td>\n<td><code class=\"language-text\">email</code></td>\n<td>ja, identifizierend</td>\n</tr>\n<tr>\n<td>D4</td>\n<td>Gruppenzugehörigkeiten</td>\n<td><code class=\"language-text\">groupAttribute</code></td>\n<td><code class=\"language-text\">groups</code></td>\n<td>ja, ggf. aussagekräftig (s. u.)</td>\n</tr>\n<tr>\n<td>D5</td>\n<td>Rollen aus dem Access Token</td>\n<td>JSON-Pfad, nur bei <code class=\"language-text\">importRealmRoles</code></td>\n<td><code class=\"language-text\">realm_access.roles</code></td>\n<td>ja, ggf. aussagekräftig</td>\n</tr>\n<tr>\n<td>D6</td>\n<td>Access Token</td>\n<td>Token-Endpunkt des IdP</td>\n<td>—</td>\n<td>mittelbar; <strong>nicht gespeichert</strong></td>\n</tr>\n<tr>\n<td>D7</td>\n<td>ID Token</td>\n<td>Token-Endpunkt des IdP</td>\n<td>—</td>\n<td>enthält <code class=\"language-text\">sub</code>; im Arbeitsspeicher, max. 12 h</td>\n</tr>\n<tr>\n<td>D8</td>\n<td><code class=\"language-text\">state</code>, PKCE-Verifier und Nonce</td>\n<td>im Plugin erzeugt</td>\n<td>—</td>\n<td>kein Personenbezug, im Arbeitsspeicher, max. 10 min</td>\n</tr>\n<tr>\n<td>D9</td>\n<td>Anmeldezeitpunkt, Vorgangsausgang</td>\n<td>implizit im Protokoll</td>\n<td>—</td>\n<td>ja, in Verbindung mit D1</td>\n</tr>\n</tbody>\n</table>\n<blockquote>\n<p><strong>Datenminimierung, Hinweis D4/D5:</strong> Gruppen- und Rollenlisten produktiver IdP-Installationen\nenthalten häufig weit mehr als Zugriffsgruppen — etwa Organisationseinheit, Fakultät,\nBeschäftigtenart oder Standort. Diese Angaben werden vollständig in\n<code class=\"language-text\">var/data/oauth2Groups/&lt;kennung>.xml</code> abgelegt. Der Verantwortliche sollte den Gruppen-Claim im\nIdP auf die für SCM-Manager erforderlichen Gruppen einschränken (Mapper-/Scope-Konfiguration);\nsiehe <a href=\"COMPLIANCE_BERICHT.md#4-befunde-und-ma%C3%9Fnahmen\">Compliance-Bericht, Befund B-03</a>.</p>\n</blockquote>\n<p>Besondere Kategorien nach Art. 9 DSGVO werden nicht verarbeitet, <strong>sofern</strong> der Gruppen-Claim keine\nentsprechenden Angaben transportiert (z. B. Gewerkschafts- oder Gesundheitsbezug in Gruppennamen).\nDie Prüfung dieser Bedingung obliegt dem Verantwortlichen.</p>\n<h2 id=\"4-prozess-1--anmeldung-authorization-code-flow\" style=\"position:relative;\"><a href=\"#4-prozess-1--anmeldung-authorization-code-flow\" aria-label=\"4 prozess 1  anmeldung authorization code flow permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Prozess 1 — Anmeldung (Authorization Code Flow)</h2>\n<p>Auslöser: Klick auf „Anmelden mit &#x3C;Provider>\", oder automatische Umleitung durch\n<code class=\"language-text\">ForceOAuth2LoginFilter</code> bei aktiviertem <code class=\"language-text\">forceLogin</code>.</p>\n<table>\n<thead>\n<tr>\n<th>Schritt</th>\n<th>Vorgang</th>\n<th>Komponente</th>\n<th>Verarbeitete Daten</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td><code class=\"language-text\">GET /api/v2/oauth2/auth?from=&lt;Ziel></code></td>\n<td><code class=\"language-text\">OAuth2AuthenticationResource</code></td>\n<td>Zielpfad (validiert: nur instanzinterne Pfade)</td>\n</tr>\n<tr>\n<td>2</td>\n<td><code class=\"language-text\">state</code> (24 Byte Zufall), PKCE-Verifier (32 Byte) und Nonce (24 Byte) erzeugen, mit Zielpfad hinterlegen</td>\n<td><code class=\"language-text\">StateStore</code>, <code class=\"language-text\">Pkce</code></td>\n<td>D8</td>\n</tr>\n<tr>\n<td>3</td>\n<td><code class=\"language-text\">state</code> als Cookie <code class=\"language-text\">X-SCM-OAuth2-State</code> setzen (<code class=\"language-text\">HttpOnly</code>, <code class=\"language-text\">SameSite=Lax</code>, <code class=\"language-text\">Secure</code> bei HTTPS, 600 s)</td>\n<td><code class=\"language-text\">StateCookie</code></td>\n<td>D8</td>\n</tr>\n<tr>\n<td>4</td>\n<td>Endpunkte ermitteln: manuell konfiguriert oder aus dem Discovery-Dokument (1 h Cache)</td>\n<td><code class=\"language-text\">EndpointResolver</code>, <code class=\"language-text\">DiscoveryClient</code></td>\n<td>keine personenbezogenen Daten</td>\n</tr>\n<tr>\n<td>5</td>\n<td>HTTP 303 zum Authorization-Endpunkt mit <code class=\"language-text\">client_id</code>, <code class=\"language-text\">redirect_uri</code>, <code class=\"language-text\">scope</code>, <code class=\"language-text\">state</code>, <code class=\"language-text\">nonce</code>, <code class=\"language-text\">code_challenge</code></td>\n<td><code class=\"language-text\">OAuth2AuthenticationResource</code></td>\n<td>D8</td>\n</tr>\n<tr>\n<td>6</td>\n<td><strong>Authentifizierung beim IdP</strong> (Passwort, MFA, Zertifikat …)</td>\n<td>außerhalb des Plugins</td>\n<td>—</td>\n</tr>\n<tr>\n<td>7</td>\n<td>Rücksprung <code class=\"language-text\">GET /api/v2/oauth2/auth/callback?code=…&amp;state=…</code></td>\n<td><code class=\"language-text\">OAuth2AuthenticationResource</code></td>\n<td><code class=\"language-text\">code</code>, D8</td>\n</tr>\n<tr>\n<td>8</td>\n<td>Prüfung: <code class=\"language-text\">state</code> stimmt mit dem Cookie dieses Browsers überein (zeitkonstanter Vergleich)</td>\n<td><code class=\"language-text\">OAuth2AuthenticationResource</code></td>\n<td>D8</td>\n</tr>\n<tr>\n<td>9</td>\n<td><code class=\"language-text\">state</code> einlösen — einmalig, danach ungültig</td>\n<td><code class=\"language-text\">StateStore</code></td>\n<td>D8</td>\n</tr>\n<tr>\n<td>10</td>\n<td>Code gegen Tokens tauschen (Server-zu-Server, <code class=\"language-text\">client_secret</code> + <code class=\"language-text\">code_verifier</code>)</td>\n<td><code class=\"language-text\">OAuth2RestClient</code></td>\n<td>D6, D7</td>\n</tr>\n<tr>\n<td>10a</td>\n<td><strong>ID Token prüfen</strong>: Signatur gegen den JWKS des IdP bzw. gegen das Client-Secret, dazu <code class=\"language-text\">iss</code>, <code class=\"language-text\">aud</code>/<code class=\"language-text\">azp</code>, Laufzeit und Nonce dieser Anmeldung; ein ungültiges Token bricht die Anmeldung ab</td>\n<td><code class=\"language-text\">TokenVerifier</code>, <code class=\"language-text\">JwksProvider</code></td>\n<td>D7</td>\n</tr>\n<tr>\n<td>11</td>\n<td>Claims vom Userinfo-Endpunkt abrufen</td>\n<td><code class=\"language-text\">OAuth2RestClient</code></td>\n<td>D1–D4</td>\n</tr>\n<tr>\n<td>12</td>\n<td>Benutzer, Gruppen und Rechte bereitstellen</td>\n<td>Prozesse 2 und 3</td>\n<td>D1–D5</td>\n</tr>\n<tr>\n<td>13</td>\n<td>ID Token für einen späteren Logout vorhalten — nur wenn es geprüft werden konnte</td>\n<td><code class=\"language-text\">IdTokenStore</code></td>\n<td>D7</td>\n</tr>\n<tr>\n<td>14</td>\n<td>SCM-Access-Token-Cookie (JWT) ausstellen</td>\n<td><code class=\"language-text\">LoginHandler</code> (Kern)</td>\n<td>D1</td>\n</tr>\n<tr>\n<td>15</td>\n<td>HTTP 303 auf den Zielpfad, <code class=\"language-text\">state</code>-Cookie löschen</td>\n<td><code class=\"language-text\">OAuth2AuthenticationResource</code></td>\n<td>—</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Abbruchbedingungen</strong> — jeweils HTTP 401 mit statischem Text, ohne Rückgabe von IdP-Details:\nfehlendes oder abweichendes <code class=\"language-text\">state</code>-Cookie, unbekanntes oder abgelaufenes <code class=\"language-text\">state</code>, fehlender Code,\nFehlermeldung des IdP, ungültiges ID Token, fehlgeschlagene Authentifizierung.</p>\n<p><strong>Grundsatz zur Tokenprüfung:</strong> Verwendet wird nur, was geprüft werden konnte. Steht keine\nSchlüsselquelle zur Verfügung (weder Discovery-URL noch konfigurierte <code class=\"language-text\">jwksUrl</code>), wird das ID Token\nverworfen und es werden keine Rollen aus dem Access Token übernommen — mit einer Warnung im\nProtokoll. Die Anmeldung selbst bleibt möglich, da die Identität aus dem über TLS abgerufenen\nUserinfo-Endpunkt stammt.</p>\n<h2 id=\"5-prozess-2--benutzerbereitstellung-und-migration\" style=\"position:relative;\"><a href=\"#5-prozess-2--benutzerbereitstellung-und-migration\" aria-label=\"5 prozess 2  benutzerbereitstellung und migration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. Prozess 2 — Benutzerbereitstellung und Migration</h2>\n<table>\n<thead>\n<tr>\n<th>Fall</th>\n<th>Verhalten</th>\n<th>Komponente</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Konto existiert nicht</td>\n<td>Neuanlage als <em>externes</em> Konto ohne Passwort</td>\n<td><code class=\"language-text\">UserInfoMapper</code>, <code class=\"language-text\">SyncingRealmHelper</code></td>\n</tr>\n<tr>\n<td>Konto existiert und ist extern (z. B. bisher LDAP)</td>\n<td>Übernahme; D2/D3 werden aktualisiert, alle übrigen Attribute bleiben erhalten</td>\n<td><code class=\"language-text\">UserMigration</code></td>\n</tr>\n<tr>\n<td>Konto existiert mit lokalem Passwort</td>\n<td>Anmeldung wird <strong>abgelehnt</strong>, sofern <code class=\"language-text\">migrateLocalUsers</code> nicht gesetzt ist</td>\n<td><code class=\"language-text\">UserMigration</code></td>\n</tr>\n<tr>\n<td>Konto existiert mit lokalem Passwort, <code class=\"language-text\">migrateLocalUsers</code> gesetzt</td>\n<td>Übernahme; das lokale Passwort wird entfernt</td>\n<td><code class=\"language-text\">UserMigration</code></td>\n</tr>\n</tbody>\n</table>\n<p>Nicht gelieferte Claims überschreiben keine gespeicherten Werte (z. B. bleibt eine vorhandene\nE-Mail-Adresse erhalten, wenn der Claim fehlt). Eine syntaktisch ungültige E-Mail-Adresse wird\nverworfen, damit die Anmeldung nicht scheitert.</p>\n<p>Da das Konto und damit die Benutzerkennung erhalten bleibt, bleiben auch alle daran gebundenen\nZuordnungen bestehen: Berechtigungen, Repository-Eigentümerschaft, API-Schlüssel, manuell gepflegte\nGruppenmitgliedschaften.</p>\n<h2 id=\"6-prozess-3--gruppen--und-berechtigungssynchronisation\" style=\"position:relative;\"><a href=\"#6-prozess-3--gruppen--und-berechtigungssynchronisation\" aria-label=\"6 prozess 3  gruppen  und berechtigungssynchronisation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6. Prozess 3 — Gruppen- und Berechtigungssynchronisation</h2>\n<p>Bei jeder Anmeldung, nach der Bereitstellung des Benutzers:</p>\n<ol>\n<li><strong>Zusammenführen</strong> von D4 und — falls aktiviert — D5. D5 wird nur aus einem signatur- und\nclaimgeprüften Access Token übernommen; andernfalls bleibt die Rollenliste leer.</li>\n<li><strong>Normalisieren</strong> der Namen: in SCM-Manager unzulässige Zeichen werden durch <code class=\"language-text\">_</code> ersetzt\n(<code class=\"language-text\">GroupNameSanitizer</code>), damit z. B. ein voller Keycloak-Gruppenpfad <code class=\"language-text\">/entwickler</code> als\n<code class=\"language-text\">_entwickler</code> nutzbar bleibt und nicht verloren geht.</li>\n<li><strong>Ablegen</strong> der normalisierten Liste in <code class=\"language-text\">var/data/oauth2Groups/&lt;kennung>.xml</code> (<code class=\"language-text\">GroupStore</code>) —\ndiese Liste ist die Grundlage der Autorisierung.</li>\n<li><strong>Abgleich der Gruppenobjekte</strong> (<code class=\"language-text\">GroupSynchronizer</code>): fehlende Gruppen werden angelegt\n(Typ <code class=\"language-text\">xml</code>, Beschreibung „Synchronized by scm-oauth2-plugin\"), Mitgliedschaften werden ergänzt\nund für Gruppen entzogen, die bei der vorherigen Anmeldung vorhanden waren und jetzt fehlen.\n<strong>Gruppen werden nie gelöscht</strong>, auch nicht wenn sie leer werden. Externe Gruppen bleiben\nunberührt.</li>\n<li><strong>Administratorrecht</strong> (<code class=\"language-text\">AdminGroupSynchronizer</code>): enthält die Liste die konfigurierte\n<code class=\"language-text\">adminGroup</code>, wird die Berechtigung <code class=\"language-text\">*</code> zugewiesen, andernfalls eine früher zugewiesene entzogen.\nBetroffen ist ausschließlich die Einzelberechtigung <code class=\"language-text\">*</code> dieses Benutzers.</li>\n</ol>\n<p>Schritte 4 und 5 laufen mit erweiterten Rechten (<code class=\"language-text\">AdministrationContext.runAsAdmin</code>), da der\nBenutzer während der Anmeldung noch nicht authentifiziert ist. Fehler in diesen Schritten werden\nprotokolliert und brechen die Anmeldung <strong>nicht</strong> ab.</p>\n<h2 id=\"7-prozess-4--autorisierung-im-laufenden-betrieb\" style=\"position:relative;\"><a href=\"#7-prozess-4--autorisierung-im-laufenden-betrieb\" aria-label=\"7 prozess 4  autorisierung im laufenden betrieb permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>7. Prozess 4 — Autorisierung im laufenden Betrieb</h2>\n<p>Der Kern fragt bei jeder Anfrage alle registrierten <code class=\"language-text\">GroupResolver</code>. <code class=\"language-text\">OAuth2GroupResolver</code> liefert\ndie bei der letzten Anmeldung gespeicherte Liste aus <code class=\"language-text\">var/data/oauth2Groups/</code>. Dadurch wirken\nGruppenrechte auch bei Zugriffen ohne Browser-Sitzung (Git über HTTP, API-Schlüssel).</p>\n<p><strong>Konsequenz für die Aktualität:</strong> Änderungen im IdP wirken erst mit der nächsten Anmeldung. Ein\nEntzug von Rechten im IdP beendet keine laufende SCM-Sitzung.</p>\n<h2 id=\"8-prozess-5--abmeldung-rp-initiated-logout\" style=\"position:relative;\"><a href=\"#8-prozess-5--abmeldung-rp-initiated-logout\" aria-label=\"8 prozess 5  abmeldung rp initiated logout permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>8. Prozess 5 — Abmeldung (RP-initiated Logout)</h2>\n<p>Nur bei aktiviertem <code class=\"language-text\">ssoLogout</code>. Der Kern beendet zuerst die lokale Sitzung, danach liefert\n<code class=\"language-text\">AfterLogoutRedirectToIdp</code> das Umleitungsziel:</p>\n<ul>\n<li><code class=\"language-text\">client_id</code></li>\n<li><code class=\"language-text\">id_token_hint</code> — das ID Token der Anmeldung aus dem <code class=\"language-text\">IdTokenStore</code>; es wird dabei entfernt.\nDa der Kern die Sitzung bereits beendet hat, wird die Benutzerkennung ersatzweise aus dem\n<code class=\"language-text\">sub</code>-Claim des noch vorhandenen Access-Token-Cookies gelesen.</li>\n<li><code class=\"language-text\">post_logout_redirect_uri</code> — die Basis-URL der Instanz; muss am IdP registriert sein.</li>\n</ul>\n<p>Ohne verfügbares ID Token (z. B. nach einem Neustart) funktioniert die Abmeldung weiterhin, der IdP\nzeigt dann ggf. eine Bestätigungsseite. Fehler führen zu „keine Umleitung\"; die lokale Abmeldung\nist in jedem Fall erfolgt.</p>\n<h2 id=\"9-prozess-6--administration-der-konfiguration\" style=\"position:relative;\"><a href=\"#9-prozess-6--administration-der-konfiguration\" aria-label=\"9 prozess 6  administration der konfiguration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>9. Prozess 6 — Administration der Konfiguration</h2>\n<p><code class=\"language-text\">GET</code>/<code class=\"language-text\">PUT</code> auf <code class=\"language-text\">/api/v2/oauth2/configuration</code>, geschützt durch\n<code class=\"language-text\">configuration:read:oauth2</code> bzw. <code class=\"language-text\">configuration:write:oauth2</code>.</p>\n<ul>\n<li>Das Client-Secret wird <strong>verschlüsselt</strong> in <code class=\"language-text\">config/oauth2.xml</code> gespeichert, von der API <strong>nie\nausgeliefert</strong> und bei leerer Übergabe unverändert beibehalten.</li>\n<li>Endpunkt-URLs werden auf absolute <code class=\"language-text\">http</code>/<code class=\"language-text\">https</code>-URLs mit Host geprüft.</li>\n<li>Bei aktiviertem Plugin ist ein Provider-Name verpflichtend.</li>\n</ul>\n<p>Die Konfiguration enthält keine personenbezogenen Daten (Ausnahme: die Angaben zum IdP-Client sind\nZugangsdaten der Instanz, keine Personendaten).</p>\n<h2 id=\"10-speicherorte-und-speicherdauer\" style=\"position:relative;\"><a href=\"#10-speicherorte-und-speicherdauer\" aria-label=\"10 speicherorte und speicherdauer permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>10. Speicherorte und Speicherdauer</h2>\n<p>Pfade relativ zum SCM-Manager-Heimatverzeichnis (Linux/Docker typisch <code class=\"language-text\">/var/lib/scm</code>).</p>\n<table>\n<thead>\n<tr>\n<th>Ort</th>\n<th>Inhalt</th>\n<th>Verwaltet von</th>\n<th>Dauer / Löschung</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code class=\"language-text\">config/oauth2.xml</code></td>\n<td>Konfiguration inkl. verschlüsseltem Client-Secret</td>\n<td>Plugin</td>\n<td>bis zur Änderung; Löschung mit dem Plugin</td>\n</tr>\n<tr>\n<td><code class=\"language-text\">var/data/oauth2Groups/&lt;kennung>.xml</code></td>\n<td>normalisierte Gruppen-/Rollenliste; <strong>der Dateiname ist die Benutzerkennung</strong></td>\n<td>Plugin</td>\n<td>wird bei jeder Anmeldung überschrieben; <strong>keine automatische Löschung</strong>, s. Befund B-01</td>\n</tr>\n<tr>\n<td>Benutzerdatenbank des Kerns</td>\n<td>D1–D3, Kennzeichen „extern\"</td>\n<td>Kern</td>\n<td>Löschung mit dem Benutzerkonto</td>\n</tr>\n<tr>\n<td>Gruppendatenbank des Kerns</td>\n<td>Gruppen und Mitgliedschaften</td>\n<td>Kern</td>\n<td>Mitgliedschaft wird bei Wegfall entzogen; Gruppenobjekt bleibt</td>\n</tr>\n<tr>\n<td>Berechtigungen des Kerns</td>\n<td>Einzelberechtigung <code class=\"language-text\">*</code> bei Admin-Gruppe</td>\n<td>Kern</td>\n<td>Entzug bei Wegfall der Gruppe</td>\n</tr>\n<tr>\n<td>Arbeitsspeicher — <code class=\"language-text\">StateStore</code></td>\n<td>offene Anmeldevorgänge (<code class=\"language-text\">state</code>, PKCE-Verifier, Nonce), max. 10.000</td>\n<td>Plugin</td>\n<td>10 Minuten oder Einlösung; Verlust bei Neustart</td>\n</tr>\n<tr>\n<td>Arbeitsspeicher — <code class=\"language-text\">JwksProvider</code></td>\n<td>öffentliche Schlüssel des IdP, keine personenbezogenen Daten</td>\n<td>Plugin</td>\n<td>1 Stunde, danach erneuter Abruf</td>\n</tr>\n<tr>\n<td>Arbeitsspeicher — <code class=\"language-text\">IdTokenStore</code></td>\n<td>ID Token je Benutzer</td>\n<td>Plugin</td>\n<td>Abmeldung oder 12 Stunden; Verlust bei Neustart</td>\n</tr>\n<tr>\n<td>Protokolldateien</td>\n<td>siehe Abschnitt 11</td>\n<td>Kern (Logback)</td>\n<td>nach Protokollierungskonzept des Betreibers</td>\n</tr>\n<tr>\n<td>Browser des Benutzers</td>\n<td><code class=\"language-text\">X-SCM-OAuth2-State</code> (600 s), Access-Token-Cookie des Kerns</td>\n<td>Plugin / Kern</td>\n<td>Ablauf bzw. Abmeldung</td>\n</tr>\n</tbody>\n</table>\n<p>Die beiden Arbeitsspeicher sind bewusst nicht persistent und <strong>nicht clusterfähig</strong>: In einem\nVerbund ohne Sitzungsbindung muss ein Anmeldevorgang, der auf einem anderen Knoten endet,\nwiederholt werden; die Abmeldung erfolgt dann ohne <code class=\"language-text\">id_token_hint</code>.</p>\n<h2 id=\"11-protokollierung\" style=\"position:relative;\"><a href=\"#11-protokollierung\" aria-label=\"11 protokollierung permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>11. Protokollierung</h2>\n<p>Das Plugin schreibt über SLF4J in das Log des Kerns. 14 Ausgaben enthalten Kennungen:</p>\n<table>\n<thead>\n<tr>\n<th>Stufe</th>\n<th>Anzahl</th>\n<th>Inhalt</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code class=\"language-text\">INFO</code></td>\n<td>7</td>\n<td>Benutzerkennung bei Gruppenanlage, Mitgliedschaftsänderung, Rechtezuweisung/-entzug, Kontoübernahme; bei einer ungültigen Mail-Adresse nur Kennung und Länge des Wertes, nicht die Adresse selbst</td>\n</tr>\n<tr>\n<td><code class=\"language-text\">WARN</code> / <code class=\"language-text\">ERROR</code></td>\n<td>4</td>\n<td>Benutzerkennung und Gruppenname bei fehlgeschlagener Synchronisation, abgelehnte Übernahme eines lokalen Kontos</td>\n</tr>\n<tr>\n<td><code class=\"language-text\">DEBUG</code></td>\n<td>3</td>\n<td>Kontoname bei Wiederverwendung, Gruppennamen bei Normalisierung</td>\n</tr>\n</tbody>\n</table>\n<p>Nicht protokolliert werden: Tokens, <code class=\"language-text\">code</code>, <code class=\"language-text\">state</code>, Nonce, PKCE-Verifier, Client-Secret,\nE-Mail-Adressen. Fehlermeldungen\ndes IdP werden ausschließlich protokolliert und nie an den Browser zurückgegeben.</p>\n<h2 id=\"12-empfänger-und-datenflüsse-nach-außen\" style=\"position:relative;\"><a href=\"#12-empf%C3%A4nger-und-datenfl%C3%BCsse-nach-au%C3%9Fen\" aria-label=\"12 empfänger und datenflüsse nach außen permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>12. Empfänger und Datenflüsse nach außen</h2>\n<table>\n<thead>\n<tr>\n<th>Richtung</th>\n<th>Empfänger</th>\n<th>Daten</th>\n<th>Kanal</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>ausgehend, Browser</td>\n<td>IdP</td>\n<td><code class=\"language-text\">client_id</code>, <code class=\"language-text\">redirect_uri</code>, <code class=\"language-text\">scope</code>, <code class=\"language-text\">state</code>, <code class=\"language-text\">code_challenge</code></td>\n<td>HTTP-Umleitung</td>\n</tr>\n<tr>\n<td>ausgehend, Server</td>\n<td>IdP Token-Endpunkt</td>\n<td><code class=\"language-text\">code</code>, <code class=\"language-text\">redirect_uri</code>, <code class=\"language-text\">client_id</code>, <code class=\"language-text\">client_secret</code>, <code class=\"language-text\">code_verifier</code></td>\n<td>HTTPS, Server-zu-Server</td>\n</tr>\n<tr>\n<td>ausgehend, Server</td>\n<td>IdP Userinfo-Endpunkt</td>\n<td>Access Token als Bearer</td>\n<td>HTTPS, Server-zu-Server</td>\n</tr>\n<tr>\n<td>ausgehend, Server</td>\n<td>IdP Discovery-Endpunkt</td>\n<td>keine personenbezogenen Daten</td>\n<td>HTTPS</td>\n</tr>\n<tr>\n<td>ausgehend, Server</td>\n<td>IdP JWKS-Endpunkt</td>\n<td>keine personenbezogenen Daten (öffentliche Schlüssel, 1 h Cache)</td>\n<td>HTTPS</td>\n</tr>\n<tr>\n<td>ausgehend, Browser</td>\n<td>IdP End-Session-Endpunkt</td>\n<td><code class=\"language-text\">client_id</code>, <code class=\"language-text\">id_token_hint</code> (enthält <code class=\"language-text\">sub</code>), <code class=\"language-text\">post_logout_redirect_uri</code></td>\n<td>HTTP-Umleitung</td>\n</tr>\n<tr>\n<td>eingehend</td>\n<td>vom IdP</td>\n<td>D1–D5, D6, D7</td>\n<td>HTTPS</td>\n</tr>\n</tbody>\n</table>\n<p>Weitere Empfänger gibt es nicht. <strong>Drittlandübermittlung:</strong> Liegt der IdP außerhalb des EWR, ist\nKapitel V DSGVO (Art. 44 ff.) durch den Verantwortlichen zu prüfen; das Plugin selbst nimmt keine\nÜbermittlung an andere Stellen vor.</p>\n<h2 id=\"13-schnittstellen\" style=\"position:relative;\"><a href=\"#13-schnittstellen\" aria-label=\"13 schnittstellen permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>13. Schnittstellen</h2>\n<table>\n<thead>\n<tr>\n<th>Endpunkt</th>\n<th>Methode</th>\n<th>Authentifizierung</th>\n<th>Zweck</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code class=\"language-text\">/api/v2/oauth2/auth</code></td>\n<td>GET</td>\n<td>anonym (<code class=\"language-text\">@AllowAnonymousAccess</code>)</td>\n<td>Anmeldung starten; HTTP 404 solange deaktiviert</td>\n</tr>\n<tr>\n<td><code class=\"language-text\">/api/v2/oauth2/auth/callback</code></td>\n<td>GET</td>\n<td>anonym</td>\n<td>Rücksprung des IdP</td>\n</tr>\n<tr>\n<td><code class=\"language-text\">/api/v2/oauth2/configuration</code></td>\n<td>GET</td>\n<td><code class=\"language-text\">configuration:read:oauth2</code></td>\n<td>Konfiguration lesen (ohne Secret)</td>\n</tr>\n<tr>\n<td><code class=\"language-text\">/api/v2/oauth2/configuration</code></td>\n<td>PUT</td>\n<td><code class=\"language-text\">configuration:write:oauth2</code></td>\n<td>Konfiguration schreiben</td>\n</tr>\n</tbody>\n</table>\n<p>Registrierte Erweiterungspunkte des Kerns: Shiro-Realm, <code class=\"language-text\">GroupResolver</code>, <code class=\"language-text\">LogoutRedirection</code>,\nIndex-Enricher, <code class=\"language-text\">ExternalAuthenticationAvailableNotifier</code>, Guice-Modul, sowie ein Servlet-Filter\n(<code class=\"language-text\">@WebElement(\"/*\")</code>) für die erzwungene Anmeldung.</p>\n<hr>\n<p><strong>Weiterführend:</strong> <a href=\"/ecfb48f1b860871431a8d921521c8fd4/COMPLIANCE_BERICHT.md\">Compliance-Bericht</a> ·\n<a href=\"/2b8b96ac9620994e713b5a4607d53444/DATENSCHUTZ_FOLGEABSCHAETZUNG.md\">Datenschutz-Folgenabschätzung</a> ·\n<a href=\"/827c0d00cff80905f727e603ab2c0778/SOURCECODE_STATISTIK.md\">Sourcecode-Statistik</a> · <a href=\"../README_de.md\">Benutzerdokumentation</a></p>","description":"Prozessbeschreibung — scm-oauth2-plugin Dokumentversion: 1.1 · Stand: 17.08.2026 · Softwarestand: scm-oauth2-plugin 1.0.2 Technische Beschreibung der…","tableOfContents":"<ul>\n<li>\n<p><a href=\"#prozessbeschreibung--scm-oauth2-plugin\">Prozessbeschreibung — scm-oauth2-plugin</a></p>\n<ul>\n<li><a href=\"#inhalt\">Inhalt</a></li>\n<li><a href=\"#1-rollen-und-abgrenzung\">1. Rollen und Abgrenzung</a></li>\n<li><a href=\"#2-zweck-der-verarbeitung\">2. Zweck der Verarbeitung</a></li>\n<li><a href=\"#3-datenkategorien\">3. Datenkategorien</a></li>\n<li><a href=\"#4-prozess-1--anmeldung-authorization-code-flow\">4. Prozess 1 — Anmeldung (Authorization Code Flow)</a></li>\n<li><a href=\"#5-prozess-2--benutzerbereitstellung-und-migration\">5. Prozess 2 — Benutzerbereitstellung und Migration</a></li>\n<li><a href=\"#6-prozess-3--gruppen--und-berechtigungssynchronisation\">6. Prozess 3 — Gruppen- und Berechtigungssynchronisation</a></li>\n<li><a href=\"#7-prozess-4--autorisierung-im-laufenden-betrieb\">7. Prozess 4 — Autorisierung im laufenden Betrieb</a></li>\n<li><a href=\"#8-prozess-5--abmeldung-rp-initiated-logout\">8. Prozess 5 — Abmeldung (RP-initiated Logout)</a></li>\n<li><a href=\"#9-prozess-6--administration-der-konfiguration\">9. Prozess 6 — Administration der Konfiguration</a></li>\n<li><a href=\"#10-speicherorte-und-speicherdauer\">10. Speicherorte und Speicherdauer</a></li>\n<li><a href=\"#11-protokollierung\">11. Protokollierung</a></li>\n<li><a href=\"#12-empf%C3%A4nger-und-datenfl%C3%BCsse-nach-au%C3%9Fen\">12. Empfänger und Datenflüsse nach außen</a></li>\n<li><a href=\"#13-schnittstellen\">13. Schnittstellen</a></li>\n</ul>\n</li>\n</ul>","frontmatter":{"title":"","subtitle":null,"description":null,"keywords":null,"displayToc":null,"image":null}}},"pageContext":{"name":"scm-oauth2-plugin","slug":"/plugins/scm-oauth2-plugin/docs/1.0.x/PROZESS_BESCHREIBUNG/","version":"1.0.x","latestVersion":"1.0.x","latestPageVersion":"1.0.x","language":"PROZESS_BESCHREIBUNG","canonicalPath":"/plugins/scm-oauth2-plugin/docs/latest/PROZESS_BESCHREIBUNG/","latestRootPath":"/plugins/scm-oauth2-plugin/docs/1.0.x/PROZESS_BESCHREIBUNG/"}},
    "staticQueryHashes": ["1973669194","2742214048","2956773653","2957019495","698804963"]}