Ü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).

UML-Sequenzdiagramm des Authorization Code Flow mit PKCE zwischen Heike Brinkmann, Browser, Mitfahrlabor und Keycloak (mit KI erstellt)

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:

Geplante Anfragen zu den Mitfahrgesuchen
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)
  1. Ergänze die Tabelle mit Hilfe der SicherheitsKonfiguration aus 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.

  1. Ergänze in der Methode sicherheitsfilter die nötigen requestMatchers-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).

  1. 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";
    }
}
  1. Schreibe die Testklasse GesuchVerwaltungSicherheitTest als @WebMvcTest mit der SicherheitsKonfiguration und vier Tests für POST /verwaltung/gesuche/1/zurueckziehen mit 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 Anmeldung oidcLogin(). (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.

  1. Die Schul-IT betreibt Keycloak im Schulnetz unter https://anmeldung.dbh-berufskolleg.example, das Mitfahrlabor läuft unter https://mitfahrlabor.dbh-berufskolleg.example. Gib an, welche Umgebungsvariablen beim Start gesetzt werden müssen, damit der Code-Stand a12 ohne Änderung an Code oder application.properties mit diesem Keycloak arbeitet, und welche Adressen die Schul-IT im Client flurmonitor-verwaltung eintragen muss. (4 Punkte)
  • KEYCLOAK_ADRESSE=https://anmeldung.dbh-berufskolleg.example: Daraus setzt application.properties Aussteller (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 weiter http://localhost:8080 als Ziel nach dem Abmelden. Spring Boot findet die Eigenschaft mitfahrlabor.keycloak.abmelde-adresse auch 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/keycloak und 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:

  1. Lina hat sich in einem Skript ein Token mit http://127.0.0.1:8180/realms/mitfahrlabor/protocol/openid-connect/token geholt. Ihre Anfrage GET /v1/angebote mit diesem Token ergibt 401 mit WWW-Authenticate: Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: The iss claim is not valid".
  2. Ein Teammitglied hat im Realm beim Mapper realm-rollen-im-id-token den 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.
  3. 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.
  4. Für die neuen Gesuche-Endpunkte hat jemand .requestMatchers(HttpMethod.POST, "/v1/gesuche").hasAuthority("NUTZER") geschrieben. Ben bekommt mit gültigem Token 403.
  5. Andrea Wolf (Admin-AW, Rolle ORGA) meldet: POST /v1/angebote/4/buchungen mit ihrem Token ergibt 403 mit dem Titel „Keine Berechtigung“.
  1. 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.

  1. Gib für jede Meldung die Abhilfe an. (5 Punkte)
  1. Token über http://localhost:8180/… holen; allgemein überall dieselbe Adresse für Keycloak verwenden (im Betrieb einen festen Hostnamen, in Keycloak mit der Option hostname festlegen).
  2. 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.
  3. th:action="@{/verwaltung/gesuche/{nr}/zurueckziehen(nr=${nummer})}" verwenden, damit Thymeleaf das CSRF-Token einfügt.
  4. hasRole("NUTZER") oder hasAuthority("ROLE_NUTZER") schreiben.
  5. 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.

  1. 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 @WebMvcTest mit oidcLogin() 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.

  1. 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.

  1. Erkläre, warum der neue Client im Gegensatz zu flurmonitor-verwaltung kein 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).

  1. 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.


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]

Kommentare gerne per Mastodon, Verbesserungsvorschläge per gitlab issue (siehe oben). Beitrag teilen: