Referenzimplementierung des IsyFact-Bausteins 'Security'
Diese Seite ist ein Teil der IsyFact-Standards. Alle Inhalte der Seite, insbesondere Texte und Grafiken, sind urheberrechtlich geschützt. Alle urheberrechtlichen Nutzungs- und Verwertungsrechte liegen beim Bundesverwaltungsamt.
Die Nutzung ist unter den Lizenzbedingungen der Creative Commons Namensnennung 4.0 International gestattet.
Hinweis: Die nachfolgende Dokumentation beinhaltet Änderungen in der Fachlichkeit, die in der Implementierung noch nicht umgesetzt sind.
Für die Implementierung ist geplant, die fachliche Domäne 'shop' durch einen Behördenkontext zu ersetzen. Die fachliche Entität 'Produkt' wird dann durch die fachliche Entität 'Antrag' ersetzt.
Weiterhin nimmt die Dokumentation für die Maven-Module zwei geplante Umbenennungen vorweg:
-
Das Modul 'ref-impl-isy-security-rw' soll umbenannt werden in 'security-service-provider'
-
Das Modul 'ref-impl-isy-security-w' soll umbenannt werden in 'security-service-consumer'
1. Ziele und Anforderungen
Ziel der Referenzimplementierung 'Security' ist es, mit Erweiterung der Referenzimplementierung 'Architektur-Durchstich' die Funktionsweise und Verwendung des IsyFact-Bausteins 'Security' zu demonstrieren.
1.1. Allgemeine Ziele
Wie bei der Referenz-Implementierung zum Architektur-Durchstich steht das Keept-it-Simple-Prinzip im Vordergrund. Es wird angestrebt, die Fachlichkeit minimal zu halten.
Darüberhinaus war es das Ziel, die Anzahl der miteinander kommunizierenden Anwendungen, die nötig sind, um die technischen Features des Security-Bausteins zu demonstrieren, sowie die Anzahl der Klassen und Methoden dieser Anwendungen möglichst klein zu halten.
Nutzungsvorgaben, Namenskonventionen, Strukturierungs-Richtlinien werden eingehalten.
1.2. Überblick über die Fachlichkeit
1.2.1. Entitäten
Wie bei der Referenzimplementierung 'Architektur-Durchstich' haben wir hier weiterhin nur das Objekt Antrag mit den Attributen Id, Antragsteller, Antragstatus.
1.2.2. Use Cases
Die Menge der Use Cases wurde um einen Anwendungsfall zur Aktualisierung von Anträgen erweitert, sodass insgesamt die folgenden Anwendungsfälle zur Verfügung stehen:
-
Suche nach Antrag anhand der ID
-
Suche nach Anträgen anhand von Attributwerten (matching substring Vergleich für den Vornamen oder Nachnamen des Antragstellers)
-
Aktualisierung eines Antrags (Update-Funktion)
1.3. Überblick über die SW-Architektur inklusive Berechtigungskonzept
Es werden zwei Anwendungen zur Verfügung gestellt:
-
Security-Service-Provider: Diese Anwendung bietet die Möglichkeit, alle drei der oben genannten Use Cases auszuführen.
-
Security-Service-Consumer: Diese Anwendung bietet nur die Möglichkeit, die Update-Funktion auszuführen. Für diesen Anwendungsfall ruft die Security-Service-Consumer-Anwendung die REST Schnittstelle der Security-Service-Provider-Anwendung auf.
Die Anwendungen arbeiten mit dem folgenden Berechtigungskonzept
-
Im Security-Service-Provider sind wie im Architektur-Durchstich
-
die Suchfunktionen weiterhin uneingeschränkt für alle Anwender (ohne jede Prüfung von Rollen und Rechten ausführbar)
-
während zur Ausführung der Update-Funktion, die im Architektur-Durchstich noch nicht vorhanden war, gefordert wird, dass der Anwender das Recht "PRIV_Recht_A" besitzt.
-
-
Im Security-Service-Consumer hingegen
-
gibt es keinerlei Suchfunktionen.
-
sondern nur eine Update-Funktion, für die gefordert wird, dass der Anwender das Recht "PRIV_Recht_B" besitzt.
-
Hinweis: Diese Konstellation bedeutet, dass im Security-Service-Consumer für Aufruf der Update-Funktion des Security-Service-Providers eine Re-Authentifizierung notwendig ist, die dem Aufrufer eine Identität mit den erforderlichen Rollen und Rechten inklusive "PRIV_Recht_A" mitgibt. Das Berechtigungskonzept wurde bewusst so gewählt, sodass ohne das technische Feature einer Re-Authentifizierung die erfolgreiche Ausführung einer Update-Funktion im Service-Consumer nicht darstellbar ist.
1.3.1. Technische Features
Die Referenz-Implementierung 'Security' soll zeigen,
-
wie die Funktionalität der BerechtigungsManager- und AuthentifizierungsManger-Interfaces des IsyFact-Bausteins Security genutzt werden kann
-
wie die '@Secured'-Annotation verwendet werden kann, um Resource-Methoden zu schützen
-
wie die '@Authenticate'-Annotation verwendet werden kann, um eine Re-Authentifizierung durchzuführen und
-
was zu tun ist, damit für externe Service-Calls die ausgehenden Requests ein zum aktuellen Security-Context passendes Token mit beinhalten.
2. Voraussetzungen
Wie in der Referenz-Implementierung 'Architektur-Durchstich' ist neben einem Java-17-JDK, einem Git-Client und eine Maven-Installation (mit Version 3.9.1 oder höher) notwendig.
Für die Referenz-Implementierung 'Security' ist außerdem eine Installation (und Konfiguration) von Keycloak notwendig. Die erforderliche Vorgehensweise zu Keycloak ist unter Keycloak Setup dokumentiert.
Die Verwendung einer IDE mit Git und Maven-Integration ist sehr empfehlenswert, aber nicht notwendig.
Hinweis: Keycloak übernimmt für den IsyFact-Security-Baustein die Rolle eines IAM Systems. Es besitzt eine eigene Datenbank. Diese Datenbank enthält (nach Einspielen einer Konfigurations-Datei) die für die Referenzimplementierung relevanten User, deren Rollen und die zugehörigen Rechte. Für jeden dieser User kann Keycloak Tokens liefern, die nur für eine bestimmte Zeit gültig sind und die genau die Rollen und Rechte dieses Users wiederspiegeln. Diese Tokens sind signiert. Somit können die Anwendungen einer Anwendungslandschaft an ihrer Systemgrenze die Tokens prüfen und auswerten.
3. Anleitung zur Implementierung
3.1. Konfiguration des Build-Managements
Die Security-Service-Provider-Anwendung und die Security-Service-Consumer-Anwendung haben beide ihre eigene pom.xml
Die folgenden Artefakte werden von beiden Anwendungen als Dependencies verlangt:
-
isy-security
-
spring-boot-starter-security
-
spring-boot-starter-web
-
spring-boot-starter-webflux
-
spring-boot-starter-validation
-
spring-boot-starter-test
-
spring-boot-starter-oauth2-client
Security-Service-Provider-Anwendung spezifische Dependencies gibt es zu:
-
spring-boot-starter-data-jpa
-
h2
Security-Service-Consumer-Anwendung spezifische Dependencies gibt es zu:
-
spring-boot-starter-oauth2-resource-server
Daran lässt sich erkennen, dass sich die beiden Anwendungen in ihrer untersten Schicht unterscheiden. Im Security-Service-Provider haben wir hier eine Datenbank, im Security-Service-Consumer dagegen einen 'resource-server'.
3.2. Konfiguration der Anwendungen
Alle anwendungsrelevanten Konfigurationseinstellungen sind in Anwendungs-spezifischen application.yml Dateien definiert.
Was den Security-Baustein betrifft, so beinhalten diese Dateien vor allem client-ids und client-secrets. Diese Properties werden in den Anwendungen verwendet und sind in KeyCloak definiert. Mit den application.yml Dateien werden diese Definitionen repliziert.
Weiterhin existiert in beiden Anwendungen eine rollenrechte.xml Datei. Diese Datei wird vom IsyFactBaustein 'Security' ausgewertet, um beim Zugriff auf geschützte Resourcen zu prüfen, ob ein User mit seinen Rollen, die er mit seinem Acess-Token mitbringt, auch die in der '@Secured' Annotation spezifizierten Rechte hat.
3.3. Java-Klassen und Interfaces
Der innere Aufbau von Security-Service-Provider und Security-Service-Consumer entspricht der 3-Schichten-Architektur des Architektur-Durchstichs, wobei im Security-Service-Consumer keine Persistenzschicht, sonderen stattdessen eine Adapterklasse zum Aufruf der REST-Schnittstelle des Security-Service-Providers implementiert ist.
In der folgenden tabellarischen Aufstellung gehen wir nicht mehr auf die Klassen und Interfaces ein, die im Architektur-Durchstich bereits beschrieben sind, sondern wir beschreiben nur noch die Klassen, die für den Aspekt 'Security' eine besondere Rolle spielen.
3.3.1. Konfigurationsklassen
Klasse |
Beschreibung |
Hinweis |
de.bund.bva.isyfact.antrag. service.rest.configuration.WebClientSecurityConfig |
Über diese Konfigurationsklasse wird sichergestellt, dass für sämtliche Requests, die zum Aufruf externer Services ausgeführt werden, ein entsprechendes Access-Token aus dem Security-Kontext extrahiert und an die aufgerufene Anwendung weitergeleitet wird. |
Das Spring-Boot-Framework erkennt Konfigurationsklassen an der Annotation '@Configuration'. |
de.bund.bva.isyfact.antrag. service.rest.configuration.OAuth2ServerSecurityConfig |
Über diese Konfigurationsklasse wird definiert, welche Resource-Methoden (abweichend vom Default) ohne JWT aufrufbar sind. |
Das Spring-Boot-Framework erkennt Konfigurationsklassen an der Annotation '@Configuration'. |
3.3.2. Adapterklasse
Die Anwendungsfall-Klasse 'AwfAntragAktualisieren'
Klasse |
Beschreibung |
Hinweis |
de.bund.bva.isyfact.antrag. core.impl.AwfAntragAktualisieren |
Hier wird die REST-Schnittstelle der Security-Service-Provider-Anwendung aufgerufen und das aktuelle AntragBo-Objekt an diese REST-Schnittstelle übergeben. |
Dieses Verhalten haben wir im Kontext der Security-Service-Consumer-Anwendung. |
de.bund.bva.isyfact.antrag. core.impl.AwfAntragAktualisieren |
Hier wird die des übergebenen Antrag-Bo-Objekts bewerkstelligt. |
Dieses Verhalten haben wir im Kontext der Security-Service-Provider-Anwendung. |
3.3.3. Architekturbild
Das nachfolgende Komponenten-Diagramm skizziert das Zusammenspiel der 'security-service-provider' und 'security-service-consumer' Anwendungen und die internen und externen Aufruf-Beziehungen zwischen ihren fachlichen Klassen.
Mit den blau-gestrichelten Linien wird dargestellt, dass der Aufruf einer REST-API Methode über das Http-Protokoll erfolgt.
Das Bild zeigt,
-
zum einen (mit durchgezogenen gezeichneten Pfeilen) Anwendungs-interne Aufruf-Beziehungen
-
Controller-Klasse → Impl-Klasse → Awf-Klasse → Repository-Interface
-
-
zum anderen (mit gestrichelten Pfeilen) die Anwendungs-übergreifenden Service-Aufrufe:
-
Api-Test-Klasse → Security-Service-Consumer-Controller-Klasse
-
Security-Service-Consumer-Adapter-Klasse → Security-Service-Provider-Controller-Klasse
-
'@Authenticate'-Annotation → Keycloak-Api und
-
'@Secured'-Annotation → Keycloak-Api
-
4. Beschreibung der Tests
Die in der Referenz-Implementierung implementierten Api-Tests sind allesamt Integrationstests. Hier wird die korrekte Funktionsweise der AntragController-Methoden verifiziert.
Die Spring-Boot-Tests dagegen konzentrieren sich eher auf die Prüfung der technischen Features des IsyFact-Security-Bausteins.
4.1. Testziel
Neben einer automatisierbaren Qualitätssicherung, die im Rahmen eines professionellen SW-Engineering eine Selbstverständlichkeit sein sollte, möchten wir darauf hinweisen, dass vor allem die API-Tests noch einen weiteren Vorteil bieten: nämlich dem Entwickler zu illustrieren, wie er die technischen Features eines IsyFact-Bausteins nutzt.
4.2. Testtechnologien
Zur Durchführung der Tests werden entweder Spring-Boot-Tests oder Api-Tests ausgeführt.
Voraussetzung für die Ausführung von Spring-Boot-Tests ist, dass die zu verwendende Keycloak-Instanz (manuell) gestartet wurde.
Voraussetzung für die Ausführung von Api-Tests ist, dass neben der Keycloak-Instanz, auch die beiden Anwendungen (Security-Service-Provider und Security-Service-Consumer) gestartet sind. Nur so nämlich lässt sich über API-Aufrufe auch deren REST-Schnittstelle erreichen.
4.3. Testklassen und Testfälle
Die nachfolgenden Tabellen geben eine Übersicht über die implementierten Testklassen und deren Testfälle. Zur weiteren Information sollte ein Entwickler die Kommentare im Java-Code heranziehen und sich über den Keycloak-Client die in Keycloak persistierte Konfiguration ansehen.
4.3.1. Security-Service-Consumer-Tests
c
Testklasse |
Testfall |
Testtechnologie |
AntragControllerApiTest |
Antrag aktualiseren |
API-Test |
4.3.2. Security-Service-Provider-Tests
Testklasse |
Testfall |
Testtechnologie |
AntragControllerApiTest |
Antrag aktualiseren |
API-Test |
AntragControllerApiTest |
Antrag mit ID suchen |
API-Test |
AntragControllerApiTest |
Antrag mit Name des Antragstellers suchen |
API-Test |
Mit den AuthenticationManagerTests wird die Funktionalität der Methoden des AuthenticationManager-Interfaces überprüft.
Testklasse |
Testfall |
Testtechnologie |
AuthenticationManagerTest |
Authentifizierung als expliziter technischer User |
Spring-Boot-Test |
AuthenticationManagerTest |
Authentifizierung als expliziter Client |
Spring-Boot-Test |
AuthenticationManagerTest |
Authentifizierung als registrierter technischer User |
Spring-Boot-Test |
AuthenticationManagerTest |
Authentifizierung als registrierter Client |
Spring-Boot-Test |
Was die BerechtigungsManagerTests betrifft, so war es das Ziel, zu demonstrieren, wie mithilfe des BerechtigungsManager-Interfaces in einer Resource-Methode Attribute eines Users ermittelt, auf erwartete Werte hin geprüft und bei Bedarf anschließend der Zugriff verweigert werden kann.
Testklasse |
Testfall |
Testtechnologie |
BerechtigungsManagerTest |
Antrag mit Name des Antragstellers suchen - als User ohne Abteilungszuordnung |
Spring-Boot-Test |
BerechtigungsManagerTest |
Antrag mit Name des Antragstellers suchen - als User mit Abteilung: nicht Zentrale |
Spring-Boot-Test |
BerechtigungsManagerTest |
Antrag mit Name des Antragstellers suchen - als User mit Abteilung: Zentrale |
Spring-Boot-Test |
Ziel der PublicResourceTests war es, die Funktionsweise der '@Secured' Annotation zu prüfen.
Testklasse |
Testfall |
Testtechnologie |
PublicResourceTest |
Aufruf einer nicht geschützten Resource-Methode - ohne Token |
Spring-Boot-Test |
PublicResourceTest |
Aufruf einer nicht geschützten Resource-Methode - mit Token |
Spring-Boot-Test |
Die SecuredResourceTests verfolgen das gleiche Ziel: Auch hier soll die Funktionsweise der '@Secured' Annotation geprüft werden.
Testklasse |
Testfall |
Testtechnologie |
SecuredResourceTest |
Aufruf einer geschützten Resource-Methode - ohne Token |
Spring-Boot-Test |
SecuredResourceTest |
Aufruf einer geschützten Resource-Methode - mit Token aber falscher Berechtigung |
Spring-Boot-Test |
SecuredResourceTest |
Aufruf einer geschützten Resource-Methode - mit Token aber korrekter Berechtigung |
Spring-Boot-Test |