1. Wiederholung High Level Flow (Beziehung ID Provider - Client - Resource Server) (**Präsentation zeigen**) 2. [Backend und Frontend gestartet] Login durchführen. In der Frontend Log-Datei (Filter auf ApiFactory und MainActivity) das Access Token, Expiration Time und die zurückgegebenen User-Daten **zeigen**. 3. Access Token Inhalt in https://jwt.io (**zeigen**) (die Expiry Time könnte man noch bei https://www.epochconverter.com/ dekodieren) 4. Backend: WebSecurityConfig **zeigen** --> hier ist die abgesicherte Route festgelegt; Resource Server Konfigurations-Details im JwtDecoder (keine weitere Erklärung). Authentication relevante Klassen im Package authentication (**aufklappen**). 5. Frontend: ApiFactory **zeigen** --> Zufügung des Authentication Headers über den Authenticator (keine weitere Erklärung) 6. Zum Einschalten des abgesicherten Zugriffs: im Frontend, UserProfileApi, im ersten @Get() ```secure/``` **einfügen**: ```java public interface UserProfileApi { @GET("secure/api/v1/profiles/{id}") LiveData> getById(@Path("id") Long id); @GET("/api/v1/profiles/{providerUserId}/provideruserid") LiveData> getByProviderUserId(@Path("providerUserId") String providerUserId); @POST("/api/v1/profiles") LiveData> updateUserProfile(@Body UserProfile newProfile); @PATCH("/api/v1/profiles/{id}") LiveData> patchUserLogin(@Path("id") Long id, @Body UserLoginProfile userLoginProfile); } ``` 7. Weiter im Backend: Die Klasse SecureUserProfileRestController im authentication package **löschen** (war nur zur Demo - sonst gibt es später Controller Konflikte) 8. Im package profile/rest die Route in der Klasse UserProfileRestController um ```secure/``` **erweitern**: ```@RequestMapping("secure/api/v1/profiles")```. 9. **Vorführen**, dass der Zugriff vom Frontend aus (GET-Button auf der User Profile Seite) mit diesen beiden Änderungen funktioniert. Im Frontend log kann man die geänderte Route sehen und dass der TokenAuthenticator ein Token abruft. 10. ```UserProfileRestController.getById()```: Falls eine Prüfung des abfragenden Users im Backend erforderlich ist, um Datensichtbarkeit einzuschränken, muss man den ```@AuthenticationPrincipal()``` einführen und die beiden Attribute Subject und Issuer abgleichen (den Code am besten **kopieren**, da es sonst viel Tipperei ist): ```java @GetMapping("{id}") public UserProfile getById(@PathVariable("id") Long id, @AuthenticationPrincipal() Jwt authenticatedUserJwt) { UserProfile userProfile = this.repo.findById(id).get(); // Quick and dirty - don't repeat at home! if (authenticatedUserJwt.getSubject().equals(userProfile.getProviderUserId()) //<--"12345" && authenticatedUserJwt.getIssuer().toString().equals(userProfile.getIdProvider())) { //************************************************************* // Die nächsten drei Zeilen existieren bereits: return this.repo.findById(id).orElseThrow(() -> { throw new ResponseStatusException(HttpStatus.NOT_FOUND); }); //************************************************************* } else { throw new ResponseStatusException(HttpStatus.FORBIDDEN); } } ``` 11. **Vorführen**: Auch so funktioniert der Zugriff vom Frontend (GET-Button) wie zuvor. 12. An der oben mit ```//<--"12345"``` markierten Stelle ```userProfile.getProviderUserId()``` durch einen willkürlichen String **ersetzen** --> Frontend-Zugriff schlägt fehl, HTTP-Fehler 403 im Log.