Übungsaufgaben zu Change Request und Keycloak: Zugriffsregeln, Tests mit Tokens und Fehlersuche für die Mitfahrgesuche
https://bildung.social/@oerinformatik/
https://oer-informatik.de/flurmonitor-change-request-keycloak-uebungsaufgaben
Change Request, Auswirkungsanalyse, OAuth 2.0, OpenID Connect, Keycloak, JWT, Resource Server, oauth2Login, SecurityFilterChain, Mitfahrgesuche, Übungsaufgaben, Prüfungsvorbereitung
tl/dr; (Bearbeitungszeit insgesamt 57 min, mehrere Aufgaben): Die Mitfahrgesuche bekommen nach dem Umbau auf Keycloak eigene Zugriffsregeln. In diesen Übungen legst Du Rollen und Regeln für Monitor, REST-API und Verwaltung fest, schreibst Integrationstests mit
oidcLogin()und stellst die Anwendung auf einen anderen Keycloak um, findest die Ursachen von 401 und 403 anhand von Symptomen und analysierst die Auswirkungen eines weiteren Change Requests [AI-Assisted]. (Zuletzt geändert am 11.11.2026)
Dieser Artikel ist Teil einer Artikelreihe über den Flurmonitor mit Thymeleaf: Projektübersicht / Scrum-Projektstart / Thymeleaf einbinden / Templates / Ansichtsmodell / Integrationstest der Web-Schicht / Konfiguration und Formatierung / Aktualisierung / Hinweise mit Formularen / Robustheit und Betrieb / GUI-Test mit Selenium / Akzeptanztest / Change Request Keycloak
Diese Übungsaufgaben gehören zum Artikel Change Request Keycloak: Flurmonitor und REST-API mit OAuth 2.0 und OpenID Connect absichern. Alle Aufgaben spielen im Projektteam der Mitfahr-App Mitfahrlabor und setzen den Übungsstrang zu den Mitfahrgesuchen fort. Ausgangspunkt ist das Projekt im Ordner src/a12-change-request-keycloak des Backend-Repositorys mit Keycloak-Realm, den beiden Filterketten und dem Startcode der Gesuche im Unterordner uebung-mitfahrgesuche (Klassen GesuchService, MitfahrgesucheController und Seite flurmonitor-gesuche.html; kopiere sie in den Ordner mitfahrlabor).
Hinweise zur Bearbeitung: Als FIA, FIDP oder FIDV musst Du zur Teil-2-Prüfung Aufgaben auf Kernkompetenz-Ebene lösen können, das sind Aufgabe 2.1 und Aufgabe 2.2. Von FIA wird zusätzlich erwartet, dass ihnen Aufgaben auf Profilkompetenz-Ebene (Aufgabe 3.1 und Aufgabe 3.2) keine Probleme bereiten. Notiere Deine Antworten zuerst vollständig, bevor Du die Beispiellösung aufklappst. Code-Aufgaben prüfst Du am besten im Projekt: ./gradlew test führt die Komponenten- und Integrationstests aus, ohne dass Keycloak laufen muss. Für Versuche mit echten Tokens startest Du Keycloak wie im Artikel beschrieben auf Port 8180. Bei Begründungen, Bezeichnern und Tabelleninhalten sind andere fachlich richtige Lösungen ebenso richtig.
Du möchtest eigene Aufgaben zum Üben von einem KI-Sprachmodell generieren lassen?
Kopiere den Text in ein KI-Sprachmodell Deiner Wahl und passe Kompetenzstufe, Anzahl, Bearbeitungszeit und Szenario bei Bedarf an. Wie die Aufgaben aufgebaut sind, beschreibt der Artikel Wie sind die Aufgaben aufgebaut?. Prüfe die Ergebnisse mit dem Lehrartikel: KI-Sprachmodelle machen Fehler.
Erstelle neue Übungsaufgaben zum Thema „Change Request und Keycloak:
Zugriffsregeln, Tests mit Tokens und Fehlersuche für die
Mitfahrgesuche“.
Bauplan: Halte Dich an Aufbau, Kompetenzstufen, Operatoren,
Anforderungsbereiche, Punkte und Zeitschätzung, die im Artikel
https://oer-informatik.de/aufgaben-aufbau beschrieben sind.
Fachliche Grundlage:
- https://oer-informatik.de/flurmonitor-change-request-keycloak
- https://oer-informatik.de/szenario-mitfahrlabor
- Stilbeispiel: https://oer-informatik.de/flurmonitor-change-request-keycloak-uebungsaufgaben
Die Aufgaben sollen Inhalte zu diesen Schlagwörtern abdecken:
- Change Request
- Auswirkungsanalyse
- OAuth 2.0
- OpenID Connect
- Keycloak
- JWT
- Resource Server
- oauth2Login
- SecurityFilterChain
- Mitfahrgesuche
Kompetenzstufe: Kernkompetenz (alternativ: Basiskompetenz, Profilkompetenz, Expertise)
Anzahl: 1 Aufgabe mit Teilaufgaben
Bearbeitungszeit in Minuten ca.: <5 bis 30 min>
Szenario: eines der Szenarien aus dem Bauplan
Vorgehen:
1. Lies zuerst die verlinkten Artikel. Kannst Du keine Webseiten
abrufen, sag mir das, statt zu raten.
2. Steht bei einer Angabe noch ein Platzhalter in <…>, frag mich
zuerst danach. Richte Punkte und Zahl der Teilaufgaben nach der
Bearbeitungszeit (ca. 0,9 min je Punkt).
3. Gib je Aufgabe Titel mit Kompetenzstufe, Ausgangssituation und
Teilaufgaben mit Operator und Punktzahl aus, dazu die geschätzte
Bearbeitungszeit.
4. Gib die Beispiellösungen mit Punkteverteilung erst aus, wenn ich
danach frage.
Aufgabe 2.1: Zugriffsregeln für die Mitfahrgesuche (Kernkompetenz)
(ca. 15 min Bearbeitungszeit)
Im Refinement nach Sprint 4 beschreibt das Folgeteam, wie die Mitfahrgesuche künftig genutzt werden sollen. Auszubildende geben über die App Gesuche auf und ziehen eigene Gesuche wieder zurück; die Schulverwaltung (Rolle ORGA) kann in der Verwaltung jedes Gesuch mit Begründung zurückziehen, etwa wenn es doppelt ist; die Monitore zeigen die Gesuche ohne Anmeldung. Die folgenden Anfragen sind geplant:
| Nr. | Anfrage | Filterkette (1 oder 2) | Regel | Antwort ohne Anmeldung |
|---|---|---|---|---|
| 1 | GET /flurmonitor/mensa/gesuche |
|||
| 2 | POST /v1/gesuche (Gesuch aufgeben) |
|||
| 3 | GET /v1/gesuche (eigene Gesuche) |
|||
| 4 | DELETE /v1/gesuche/3 (Gesuch zurückziehen) |
|||
| 5 | POST /verwaltung/gesuche/2/zurueckziehen (Formular) |
- Ergänze die Tabelle mit Hilfe der
SicherheitsKonfigurationaus dem Code-Stand a12: In welche Filterkette fällt die Anfrage, welche Regel soll gelten (öffentlich, angemeldet, Rolle …), und wie antwortet die Anwendung, wenn niemand angemeldet ist? (10 Punkte)
| Nr. | Anfrage | Filterkette | Regel | Antwort ohne Anmeldung |
|---|---|---|---|---|
| 1 | GET /flurmonitor/mensa/gesuche |
2 | öffentlich; schon durch GET /flurmonitor/** erlaubt |
200 mit der Seite |
| 2 | POST /v1/gesuche |
2 | Rolle NUTZER (neue Regel) | 401 mit WWW-Authenticate: Bearer … |
| 3 | GET /v1/gesuche |
2 | angemeldet (schon durch anyRequest().authenticated()) |
401 |
| 4 | DELETE /v1/gesuche/3 |
2 | Rolle NUTZER oder ORGA (neue Regel), ob eigenes Gesuch: im Service | 401 |
| 5 | POST /verwaltung/gesuche/2/zurueckziehen |
1 | Rolle ORGA (schon durch /verwaltung/**), dazu CSRF-Token |
302 zu /oauth2/authorization/keycloak |
Bewertung: je Zeile 2 Punkte (Filterkette und Regel 1 Punkt, Antwort 1 Punkt). Für Zeile 3 ist auch „Rolle NUTZER“ richtig, wenn begründet ist, dass ORGA-Konten keine eigenen Gesuche haben.
- Ergänze in der Methode
sicherheitsfilterdie nötigenrequestMatchers-Zeilen und gib an, an welcher Stelle sie stehen müssen. (4 Punkte)
.requestMatchers(HttpMethod.POST, "/v1/angebote", "/v1/angebote/*/buchungen").hasRole("NUTZER")
// MON-13g: Gesuche aufgeben nur NUTZER, zurückziehen NUTZER (eigene) oder ORGA
.requestMatchers(HttpMethod.POST, "/v1/gesuche").hasRole("NUTZER")
.requestMatchers(HttpMethod.DELETE, "/v1/gesuche/*").hasAnyRole("NUTZER", "ORGA")Bewertung: zwei Regeln mit richtiger Methode, richtigem Pfadmuster und richtiger Rolle (je 1 Punkt); Position vor .anyRequest().authenticated() (1 Punkt), weil Spring Security die Regeln der Reihe nach prüft und die erste passende gilt; GET /v1/gesuche braucht keine eigene Regel (1 Punkt). Für Verwaltung und Monitor ändert sich nichts.
Geprüft mit einem @WebMvcTest: POST /v1/gesuche ohne Token 401, mit jwt() und ROLE_ORGA 403, mit ROLE_NUTZER 404 (Endpunkt gibt es noch nicht, die Regel lässt durch).
- Ben (Funkenflug) und Lina (Rotkehlchen) haben beide die Rolle NUTZER. Begründe, warum die Filterkette nicht verhindern kann, dass Ben Linas Gesuch löscht, und wo diese Prüfung hingehört. (2 Punkte)
Die Regeln der Filterkette kennen nur Adresse, Methode und Rechte aus dem Token, nicht die Daten: Wem Gesuch 3 gehört, steht in der Datenbank (1 Punkt). Die Prüfung gehört in den Service, der wie bei den Angeboten die Anmeldung aus AktuelleAnmeldung mit der Person des Gesuchs vergleicht und sonst eine KeineBerechtigungException wirft (403) (1 Punkt).
Aufgabe 2.2: Tests mit oidcLogin und ein anderer Keycloak (Kernkompetenz)
(ca. 11 min Bearbeitungszeit)
Für das Zurückziehen in der Verwaltung hat das Team einen ersten Controller geschrieben:
package de.dbh.mitfahrlabor.web.verwaltung;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import de.dbh.mitfahrlabor.service.GesuchService;
/** MON-13g (Entwurf): Die Schulverwaltung zieht ein unpassendes Gesuch zurück (Formular mit Grund). */
@Controller
public class GesuchVerwaltungController {
private final GesuchService gesuchService;
public GesuchVerwaltungController(GesuchService gesuchService) {
this.gesuchService = gesuchService;
}
@PostMapping("/verwaltung/gesuche/{nummer}/zurueckziehen")
public String zurueckziehen(@PathVariable int nummer, @RequestParam String grund) {
gesuchService.zurueckziehen(nummer, grund);
return "redirect:/verwaltung/gesuche";
}
}- Schreibe die Testklasse
GesuchVerwaltungSicherheitTestals@WebMvcTestmit derSicherheitsKonfigurationund vier Tests fürPOST /verwaltung/gesuche/1/zurueckziehenmit dem Grund „doppelt“: ohne Anmeldung (Weiterleitung zu Keycloak), angemeldet mit Rolle NUTZER (403), angemeldet mit Rolle ORGA, aber ohne CSRF-Token (403), angemeldet mit Rolle ORGA und CSRF-Token (Weiterleitung auf/verwaltung/gesuche, Service aufgerufen). Nutze für die AnmeldungoidcLogin(). (8 Punkte)
package de.dbh.mitfahrlabor.web.verwaltung;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oidcLogin;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import de.dbh.mitfahrlabor.service.GesuchService;
import de.dbh.mitfahrlabor.web.SicherheitsKonfiguration;
@WebMvcTest(GesuchVerwaltungController.class)
@Import(SicherheitsKonfiguration.class)
class GesuchVerwaltungSicherheitTest {
private static final String ADRESSE = "/verwaltung/gesuche/1/zurueckziehen";
@Autowired
private MockMvcTester mvc;
@MockitoBean
private GesuchService gesuchService;
@Test
void ohneAnmeldungGehtEsZuKeycloak() {
assertThat(mvc.post().uri(ADRESSE).param("grund", "doppelt").with(csrf()))
.hasStatus(HttpStatus.FOUND)
.redirectedUrl().endsWith("/oauth2/authorization/keycloak");
verify(gesuchService, never()).zurueckziehen(anyInt(), anyString());
}
@Test
void nutzerDuerfenNicht() {
assertThat(mvc.post().uri(ADRESSE).param("grund", "doppelt").with(csrf())
.with(oidcLogin().authorities(new SimpleGrantedAuthority("ROLE_NUTZER"))))
.hasStatus(HttpStatus.FORBIDDEN);
verify(gesuchService, never()).zurueckziehen(anyInt(), anyString());
}
@Test
void ohneCsrfTokenAuchOrgaNicht() {
assertThat(mvc.post().uri(ADRESSE).param("grund", "doppelt")
.with(oidcLogin().authorities(new SimpleGrantedAuthority("ROLE_ORGA"))))
.hasStatus(HttpStatus.FORBIDDEN);
verify(gesuchService, never()).zurueckziehen(anyInt(), anyString());
}
@Test
void orgaZiehtZurueckUndWirdUmgeleitet() {
assertThat(mvc.post().uri(ADRESSE).param("grund", "doppelt").with(csrf())
.with(oidcLogin().idToken(token -> token.claim("pseudonym", "Sekretariat-HB"))
.authorities(new SimpleGrantedAuthority("ROLE_ORGA"))))
.hasStatus(HttpStatus.FOUND)
.redirectedUrl().isEqualTo("/verwaltung/gesuche");
verify(gesuchService).zurueckziehen(1, "doppelt");
}
}Bewertung: Testklasse mit @WebMvcTest, @Import(SicherheitsKonfiguration.class) und gemocktem GesuchService (2 Punkte); je Test 1,5 Punkte (Anmeldung bzw. CSRF richtig gesetzt, Status und Ziel der Weiterleitung, Prüfung, ob der Service aufgerufen wurde).
Wichtig ist, dass oidcLogin().authorities(…) die Rechte vollständig ersetzt: Ohne ROLE_ORGA hat die Anmeldung nur OIDC_USER und Scopes. Im ersten Test gehört csrf() dazu, damit wirklich die fehlende Anmeldung geprüft wird und nicht das fehlende Token. Alle vier Tests laufen grün, ohne dass Keycloak läuft.
- Die Schul-IT betreibt Keycloak im Schulnetz unter
https://anmeldung.dbh-berufskolleg.example, das Mitfahrlabor läuft unterhttps://mitfahrlabor.dbh-berufskolleg.example. Gib an, welche Umgebungsvariablen beim Start gesetzt werden müssen, damit der Code-Stand a12 ohne Änderung an Code oderapplication.propertiesmit diesem Keycloak arbeitet, und welche Adressen die Schul-IT im Clientflurmonitor-verwaltungeintragen muss. (4 Punkte)
KEYCLOAK_ADRESSE=https://anmeldung.dbh-berufskolleg.example: Daraus setztapplication.propertiesAussteller (issuer-uri) und alle Endpunkte des Clients zusammen (1 Punkt).KEYCLOAK_CLIENT_SECRET=<Geheimnis aus Keycloak>: ersetzt den Übungswert (1 Punkt).MITFAHRLABOR_KEYCLOAK_ABMELDE_ADRESSE=https://anmeldung.dbh-berufskolleg.example/realms/mitfahrlabor/protocol/openid-connect/logout?client_id=flurmonitor-verwaltung&post_logout_redirect_uri=https://mitfahrlabor.dbh-berufskolleg.example/flurmonitor/foyer: Die Abmeldeadresse enthält sonst weiterhttp://localhost:8080als Ziel nach dem Abmelden. Spring Boot findet die Eigenschaftmitfahrlabor.keycloak.abmelde-adresseauch unter diesem Namen (Punkte und Bindestriche werden zu Unterstrichen, Großbuchstaben) (1 Punkt).- Im Client: Redirect-URI
https://mitfahrlabor.dbh-berufskolleg.example/login/oauth2/code/keycloakund als „Valid post logout redirect URI“https://mitfahrlabor.dbh-berufskolleg.example/flurmonitor/foyer(1 Punkt).
Hinweis: Steht das Mitfahrlabor hinter einem Reverse Proxy, muss es dessen Kopfzeilen auswerten (server.forward-headers-strategy=native), damit {baseUrl} in der Redirect-URI mit https beginnt.
Aufgabe 3.1: 401 oder 403? Fehlersuche nach dem Umbau (Profilkompetenz)
(ca. 18 min Bearbeitungszeit)
In der ersten Woche nach dem Umbau gehen beim Team fünf Meldungen ein:
- Lina hat sich in einem Skript ein Token mit
http://127.0.0.1:8180/realms/mitfahrlabor/protocol/openid-connect/tokengeholt. Ihre AnfrageGET /v1/angebotemit diesem Token ergibt401mitWWW-Authenticate: Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: The iss claim is not valid". - Ein Teammitglied hat im Realm beim Mapper
realm-rollen-im-id-tokenden Schalter „Add to ID token“ ausgeschaltet, weil das ID Token „zu groß“ war. Seitdem meldet sich Heike Brinkmann bei Keycloak erfolgreich an, landet danach aber auf einer Fehlerseite mit Status 403. Anfragen an die REST-API mit ihrem Access Token funktionieren. - Für die Verwaltung der Gesuche gibt es eine neue Seite. Das Formular steht dort als
<form action="/verwaltung/gesuche/2/zurueckziehen" method="post">. Die Seite lädt, nach dem Absenden kommt 403. - Für die neuen Gesuche-Endpunkte hat jemand
.requestMatchers(HttpMethod.POST, "/v1/gesuche").hasAuthority("NUTZER")geschrieben. Ben bekommt mit gültigem Token 403. - Andrea Wolf (Admin-AW, Rolle ORGA) meldet:
POST /v1/angebote/4/buchungenmit ihrem Token ergibt 403 mit dem Titel „Keine Berechtigung“.
- Bestimme für jede Meldung, ob die Anmeldung oder die Berechtigung scheitert, und nenne die Ursache. (10 Punkte)
| Nr. | scheitert | Ursache |
|---|---|---|
| 1 | Anmeldung (401) | Der Aussteller im Token ist http://127.0.0.1:8180/realms/mitfahrlabor, der Resource Server erwartet laut issuer-uri http://localhost:8180/…. Keycloak schreibt die Adresse, unter der es angefragt wurde, in iss. |
| 2 | Berechtigung (403) | Die Verwaltung liest die Rollen aus dem ID Token (rollenAusIdToken). Ohne den Mapper steht dort kein realm_access.roles, die Anmeldung hat nur OIDC_USER und Scopes, hasRole("ORGA") ist nicht erfüllt. Die REST-API liest das Access Token, dort steht die Rolle weiter. |
| 3 | Berechtigung (403) | Das CSRF-Token fehlt: Nur th:action fügt das versteckte Feld _csrf ein. Die Verwaltungskette prüft es bei jedem POST. |
| 4 | Berechtigung (403) | hasAuthority("NUTZER") verlangt das Recht NUTZER, der Converter erzeugt aber ROLE_NUTZER. hasRole("NUTZER") ergänzt das Präfix selbst. |
| 5 | Berechtigung (403), gewollt | Kein Fehler: Buchen ist nur für die Rolle NUTZER erlaubt; die Schulverwaltung fährt nicht mit. |
Bewertung: je Meldung 2 Punkte (Einordnung 1 Punkt, Ursache 1 Punkt). Für Meldung 5 gibt es den zweiten Punkt nur, wenn erkannt ist, dass es sich um gewolltes Verhalten handelt.
- Gib für jede Meldung die Abhilfe an. (5 Punkte)
- Token über
http://localhost:8180/…holen; allgemein überall dieselbe Adresse für Keycloak verwenden (im Betrieb einen festen Hostnamen, in Keycloak mit der Optionhostnamefestlegen). - Mapper wieder für das ID Token einschalten (und den Realm-Export aktualisieren). Alternativ die Rollen über den UserInfo-Endpunkt laden; das kostet aber bei jeder Anmeldung eine Anfrage mehr.
th:action="@{/verwaltung/gesuche/{nr}/zurueckziehen(nr=${nummer})}"verwenden, damit Thymeleaf das CSRF-Token einfügt.hasRole("NUTZER")oderhasAuthority("ROLE_NUTZER")schreiben.- Nichts ändern; Andrea Wolf erklären, dass ORGA-Konten nicht buchen. Will der Product Owner das ändern, ist es ein neuer Eintrag im Product Backlog.
Bewertung: je Meldung 1 Punkt.
- Nenne für die Meldungen 2, 3 und 4 die niedrigste Testebene, auf der ein automatischer Test den Fehler hätte finden können, und begründe für Meldung 2, warum dort ein
@WebMvcTestmitoidcLogin()nicht ausreicht. (4 Punkte)
Meldung 3: Integrationstest der Web-Schicht, der die Seite rendert und prüft, dass das Formular ein Feld _csrf enthält (wie der vorhandene Test der Hinweise) (1 Punkt). Meldung 4: Integrationstest der Web-Schicht mit jwt().authorities(new SimpleGrantedAuthority("ROLE_NUTZER")), der 403 statt 2xx/404 meldet (1 Punkt). Meldung 2: erst der GUI- oder Akzeptanztest gegen einen Keycloak mit dem geänderten Realm (1 Punkt). oidcLogin() setzt Rechte und Claims selbst; ob Keycloak die Rolle wirklich ins ID Token schreibt, prüft nur ein Test mit echtem Keycloak, und auch der nur, wenn die Änderung im Realm-Export landet, den die Pipeline importiert. Deshalb gehört jede Änderung am Realm in die Datei im Repository (1 Punkt).
Aufgabe 3.2: Auswirkungsanalyse für einen weiteren Change Request (Profilkompetenz)
(ca. 13 min Bearbeitungszeit)
Kurz nach Projektende geht CR-03 ein: Die neue Web-App mit Vue soll Auszubildenden erlauben, Gesuche aufzugeben und zurückzuziehen. Sie läuft vollständig im Browser (in der Entwicklung unter http://localhost:5173), meldet sich über den Realm mitfahrlabor an und ruft die REST-API des Mitfahrlabors direkt mit dem Access Token auf. Die Endpunkte /v1/gesuche aus Aufgabe 2.1 sollen dafür gebaut werden.
- Stelle eine Auswirkungsanalyse für CR-03 als Tabelle mit den Spalten Bereich, Auswirkung und Aufwand (keiner, gering, mittel, hoch) auf. Berücksichtige mindestens Keycloak, Sicherheitskonfiguration, Fachlogik und Datenbank, Vertrag
openapi.yaml, Tests und Datenschutz. (8 Punkte)
| Bereich | Auswirkung | Aufwand |
|---|---|---|
| Keycloak | neuer öffentlicher Client (z. B. mitfahrlabor-web) mit Authorization Code Flow und PKCE, Redirect-URI und Web Origin http://localhost:5173, ohne Geheimnis; Realm-Export aktualisieren |
gering |
| Sicherheitskonfiguration | Regeln für /v1/gesuche (Aufgabe 2.1); CORS erlaubt http://localhost:5173 schon (mitfahrlabor.cors.erlaubte-urspruenge), für DELETE und den Header Authorization prüfen |
gering |
| Fachlogik, Datenbank | Gesuche bisher nur als Liste im Arbeitsspeicher: Entity, Repository, Service mit Prüfung „eigenes Gesuch“ | hoch |
Vertrag openapi.yaml |
neue Pfade /v1/gesuche, Schema Gesuch, Sicherheitsschema bearerAuth |
mittel |
| Tests | Komponententests für den Service; @WebMvcTest mit jwt(); Systemtests mit TestTokens; Playwright-Tests der Web-App gegen Keycloak |
mittel |
| Datenschutz | Gesuche zeigen am Monitor weiter keine Namen; die App zeigt nur eigene Gesuche | gering |
| Unverändert | Verwaltung (oauth2Login), Flurmonitore, Angebote und Buchungen |
– |
Bewertung: je genanntem Bereich mit passender Auswirkung 1 Punkt (höchstens 6), stimmige Aufwandseinschätzung 1 Punkt, Nennung dessen, was unverändert bleibt, 1 Punkt.
- Erkläre, warum der neue Client im Gegensatz zu
flurmonitor-verwaltungkein Client-Geheimnis bekommt und was ihn trotzdem schützt. (3 Punkte)
Der Code der Web-App liegt vollständig im Browser; jedes Geheimnis darin könnte jede Person auslesen. Er ist deshalb ein öffentlicher Client (1 Punkt). Statt des Geheimnisses schützt PKCE den Tausch des Codes: Nur die Instanz der App, die den code_verifier erzeugt hat, kann den Code einlösen (1 Punkt). Dazu kommen die festen Redirect-URIs und Web Origins, kurze Lebensdauern der Tokens und die Prüfung der Rollen im Resource Server (1 Punkt).
- Das Folgeteam schätzt CR-03 auf 13 Story Points, MON-16 hatte 8. Nimm Stellung, ob CR-03 als ein Eintrag in den nächsten Sprint gehört oder geschnitten werden sollte, und schlage gegebenenfalls einen Schnitt vor. (3 Punkte)
13 Story Points sind fast eine ganze durchschnittliche Velocity (14,7); ein Eintrag dieser Größe birgt das Risiko, am Sprintende nicht fertig zu sein, und liefert erst spät Nutzen (1 Punkt). Sinnvoll ist ein Schnitt nach Nutzen, nicht nach Schichten, zum Beispiel: (1) Gesuche dauerhaft speichern und über GET /v1/gesuche lesen, (2) Gesuch aufgeben, (3) eigenes Gesuch zurückziehen; den Client in Keycloak bringt der erste Eintrag mit (1 Punkt). Jeder Teil ist für sich abnehmbar und kann nach Rang des Product Owners eingeplant werden (1 Punkt). Eine begründete Gegenposition (ein Eintrag, weil die Teile ohne die App nicht nutzbar sind) ist ebenfalls richtig, wenn sie das Risiko anspricht.
Links und weitere Informationen
zum Lehrartikel: Change Request Keycloak: Flurmonitor und REST-API mit OAuth 2.0 und OpenID Connect absichern
zum Szenario: Szenario Mitfahrlabor mit Personas und Flurmonitoren
als Nachschlagewerk: Spring Security: Testing OAuth 2.0 und Keycloak Server Administration Guide
zum Weiterlesen: RFC 7636 PKCE und OAuth 2.0 for Browser-Based Applications
Hinweis zur Nachnutzung als Open Educational Resource (OER)
Dieser Artikel und seine Texte, Bilder, Grafiken, Code und sonstiger Inhalt sind - sofern nicht anders angegeben - lizenziert unter CC BY 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: “Übungsaufgaben zu Change Request und Keycloak: Zugriffsregeln, Tests mit Tokens und Fehlersuche für die Mitfahrgesuche” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/flurmonitor-change-request-keycloak-uebungsaufgaben veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/java-springboot/Backend. Erstellt mit KI-Assistenz; von mir umfassend redaktionell überarbeitet, geprüft und freigegeben. Stand: 11.11.2026.
[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]
