[JAVA] Einführung in die Keycloak-Entwicklung

Erstausgabe: 2018/8/1

Verfasser: Koji Mogi, Hitachi, Ltd.

Einführung

Keycloak (https://www.keycloak.org/) ist eine Open-Source-Software zur Verwaltung des Identitätszugriffs. Jeder kann zur Entwicklung von Keycloak beitragen, da die Entwicklung auf Community-Basis erfolgt, aber ich denke, es ist schwierig, ohne Kenntnis der Entwicklungsmethode und der Community-Regeln zu beginnen. Dieses Mal möchte ich das Wissen teilen, das ich durch den Inhalt der Patch-Entwicklung (# 5163) erhalten habe. ..

Diese Informationen finden Sie in README.md und HackingOnKeycloak.md im Keycloak-Repository. com / keycloak / keycloak / blob / master / misc / HackingOnKeycloak.md), [HOW-TO-RUN.md](https://github.com/keycloak/keycloak/blob/master/testsuite/integration-arquillian/HOW -TO-RUN.md) basiert auf dem Inhalt.

Dieser Artikel ist eine Ergänzung zu den Inhalten der 3. Studiengruppe der OSS Security Technology Association.

Inhaltsverzeichnis

Was wurde entwickelt

Keycloak verfügt über eine Funktion namens Identity Brokering. Das Ergebnis der Authentifizierung bei einem externen OpenID Connect-Anbieter kann mit Keycloak verwendet werden. Keycloak verfügt auch über Einstellungen für die Verbindung zu beliebten Anbietern wie Google und Facebook.

brokering.png

Da der Benutzerauthentifizierungsprozess einschließlich des Bildschirms von uns selbst durchgeführt werden musste, haben wir ihn so eingestellt, dass er mithilfe von Identity Brokering zu unserer eigenen Authentifizierungsanwendung umgeleitet wird. In dieser Authentifizierungsanwendung musste der Client jedoch Parameter außerhalb der Spezifikationen von OpenID Connect senden. In Keycloaks Identity Brokering wird der Abfrageparameter, den Sie unabhängig angeben möchten, an den externen Identitätsanbieter (= Authentifizierungsbildschirm) übertragen. nicht.

Um dies zu lösen, haben wir unseren eigenen Identity Provider implementiert, der Parameter mithilfe des Identity Provider SPI (einer Schnittstelle zur Erweiterung von Identity Brokering) überträgt. Ich hatte jedoch das Gefühl, dass es andere Anwendungsfälle gab, in denen Parameter außerhalb der OpenID Connect-Spezifikation verwendet wurden, und entschied mich daher, als allgemeine Funktion einen Beitrag zur Community zu leisten.

Funktionsvorschläge, Fehlerberichte

Keycloak verwendet die folgenden Tools, um neue Funktionen vorzuschlagen und Fehler zu melden.

Wenn Sie einen Fehler finden, erstellen Sie zuerst ein Ticket mit Details in JIRA und dann eine Pull-Anfrage mit der ID dieses Tickets im Titel.

Von hier aus werden wir Ihnen vorstellen, wie Sie die Patch-Entwicklungsumgebung vorbereiten, den Code ändern, den Test ausführen usw., basierend auf dem Wissen über die eigentliche Patch-Entwicklung.

Vorbereitung für die Umsetzung

Verzweigen Sie zuerst das Keycloak-Repository und klonen Sie das Repository.

$ git clone https://github.com/<username>/keycloak

Wir werden in diesem geklonten Verzeichnis vorbereiten.

Wie zu bauen

Erstellen Sie den Quellcode mit dem folgenden Befehl.

$ mvn install -DskipTests=true
$ cd distribution
$ mvn install

Tests können je nach Umgebung fehlschlagen. Es empfiehlt sich daher, die Tests zur Erstellungszeit zu überspringen, zu beheben und dann nur die relevanten Tests auszuführen. Wenn der obige Befehl ausgeführt wird, wird der Build (.tar.gz, .zip) unter "Distribution / Server-Dist / Target" ausgegeben. Sie können Keycloak auch ausführen, indem Sie diese entpacken und "bin / standalone.sh" ausführen.

In IDE importieren

Als nächstes bereiten wir uns auf die Entwicklung mit IDE vor. Dieses Mal habe ich Eclipse (Oxygen) als IDE verwendet. Importieren Sie das Maven-Projekt in Eclipse, indem Sie die Datei "pom.xml" (die das Projekt "keycloak-parent" sein wird) direkt unter dem Keycloak-Repository angeben.

Aufgrund der großen Anzahl von Projekten (300+) wird der Import einige Zeit dauern.

Debuggen mit IDE (Eclipse)

Um Keycloak in der Entwicklung zu starten, führen Sie mvn -f testsuite / utils / pom.xml exec: java -Pkeycloak-server aus, wie in README.md beschrieben. Nach dem Starten des Keycloak-Servers können Sie über localhost: 8081 / auth / auf die Keycloak-GUI zugreifen.

Wie oben erwähnt, ist es möglich, es mit Maven über die Befehlszeile auszuführen, aber da wir Eclipse verwenden, können wir dort debuggen. Wenn Sie sich die im obigen Befehl angegebene pom.xml ansehen, wird die Klasse org.keycloak.testsuite.KeycloakServer des Projekts keycloak-testsuite-utils ausgeführt. Geben Sie diese Klasse zum Debuggen an. Ausführen. Die Einstellungen sind in der folgenden Abbildung dargestellt.

debug_config.png

Sie können jetzt Eclipse zum Debuggen von Keycloak verwenden.

Konfigurieren Sie die Datenbankeinstellungen weiter. Die Standardeinstellung verwendet InMemoryDB von H2DB. Wenn diese Einstellung jedoch unverändert bleibt, geht sie bei jedem Neustart verloren. Da es schwierig ist, es mehrmals zurückzusetzen, stellen Sie es so ein, dass es in einer Datei gespeichert wird. Geben Sie als Startargument -Dkeycloak.connectionsJpa.url = jdbc: h2: ./keycloak; AUTO_SERVER = TRUE an. Die Einstellungsmethode in Eclipse ist in der folgenden Abbildung dargestellt.

persist_settings.png

Jetzt, da wir für die Entwicklung einschließlich des Debuggens bereit sind, werden wir den Code ändern.

Code korrigieren

Von hier aus erklären wir die einfache Architektur von Keycloak basierend auf dem Inhalt, der die Funktion "Benutzerdefinierte Parameter mit der Identity Brokering-Funktion an einen externen Identitätsanbieter übertragen" implementiert.

Details der Korrektur

Die Parameterwerte beim Zugriff auf den Keycloak-Autorisierungsendpunkt wurden in einem Modell namens AuthorizationSession gespeichert, einschließlich nicht spezifizierter Parameter. In dem Teil, in dem die RedirectURL zum externen Identitätsanbieter erstellt wird, habe ich sie so geändert, dass die nicht spezifikationsbezogenen Parameter aus der Autorisierungssitzung abgerufen und der URL hinzugefügt werden.

Anstatt alle Parameter weiterzuleiten, werden auch nur die in den Einstellungen für Identity Brokering angegebenen Parameter weitergeleitet.

Speicherort der mit dem Identitätsanbieter verbundenen Dateien

Grundfunktionen wie Authentifizierung und Autorisierung sowie Identity Brokering-Funktionen werden in einem Projekt namens "Keycloak-Services" implementiert. Dieses Projekt implementiert den SPI, der durch "keycloak-spi", "keycloak-spi-private" definiert ist. Wie bei der Entwicklung eines Plug-Ins mit SPI werden "Provider" und "ProviderFactory" paarweise implementiert.

Der OpenID Connect Identity Provider ist in einer Klasse namens "org.keycloak.broker.oidc.OIDCIdentityProvider" implementiert. Die Weiterleitungs-URL zum externen Identitätsanbieter wurde mit der Methode createAuthorizationUrl von org.keycloak.broker.oidc.AbstractOauth2IdentityProvider erstellt, die von dieser Klasse geerbt wurde. Daher habe ich diese Methode geändert. Es war.

GUI ändert sich

Um nur bestimmte externe Parameter zu übertragen, wurde dem Einstellungselement des Identitätsanbieters ein Element zum Festlegen der zu übertragenden Parameter hinzugefügt.

label.png

Die Keycloak-GUI wurde mit AngularJS (1.6) erstellt. Sie finden die "Vorlage" und den Javascript-Code unter den "Keycloak-Themen" des Projekts. Da die Einstellungselemente des Idenity-Anbieters so konzipiert wurden, dass der gesamte Inhalt des Formulars an die API gesendet wird, kann es einfach implementiert werden, indem das Formular und der Tooltip zur Vorlage "Realm-Identity-Provider-oidc.html" hinzugefügt werden.

Ab Juli 2018 wurde unter "Keycloak-Themen" ein Ordner namens "Keycloak-Vorschau" erstellt. Es scheint, dass die GUI der Keycloak-Administratorkonsole neu erstellt wurde, und als ich sie leicht betrachtete, schien sie mit Angular 5 erstellt worden zu sein. Ich habe Pull-Anfragen wie Responsive Support gesehen, daher würde ich gerne erwarten und warten.

Änderung des DB-Schemas

Da ich die Einstellungselemente von Identity Provider erweitert habe, hielt ich es für notwendig, das DB-Schema zu ändern. Da die Einstellungselemente jedoch in der Tabelle "IDENTITY_PROVIDER_CONFIG" in Form eines Schlüsselwerts registriert wurden, musste das Schema nicht geändert werden. Es wird auch von Map <String, String> im Code verwaltet. Angesichts der Tatsache, dass es viele Änderungen an den Einstellungselementen gibt, hielt ich es für sinnvoll, dies so vorzunehmen, dass es ohne Schemaänderungen behandelt werden kann.

Dieses Mal musste ich das Schema nicht ändern, aber wenn ich Änderungen an der Datenbank vornehmen muss, werde ich sie ändern, da sich die Modelle im Projekt "keycloak-model-jpa" befinden.

Testimplementierung

Keycloak verwendet ein Testframework namens Arquiilian, um Integrationstests durchzuführen. Identity Brokering-Tests sind in einem Projekt namens "Integration-Arquiilian-Tests-Base" ("Testsuite \ Integration-Arquillian \ Tests \ Base") enthalten.

Das Testen des externen Identitätsanbieters wurde unterstützt, indem zwei Bereiche verwendet wurden, "Verbraucher" und "Anbieter", wie in der Abbildung gezeigt.

provider-consumer.png

Bei den vorhandenen Tests gab es einen Test, bei dem die Abfrageparameter überprüft wurden. Daher habe ich ihn zur Beschreibung des Tests verwendet.

Führen Sie den folgenden Befehl aus, um den implementierten Test auszuführen.

$ mvn -f testsuite/integration-arquillian/tests/base/pom.xml test

Dadurch werden die grundlegenden Funktionstests ausgeführt, aber jeder Test dauert lange, und aufgrund der Anzahl der Tests dauert es eine beträchtliche Zeit, bis alle Tests abgeschlossen sind. Um einen bestimmten Test auszuführen, geben Sie den Klassennamen mit -Dtest an.

$ mvn -f testsuite/integration-arquillian/tests/base/pom.xml test -Dtest=org.keycloak.testsuite.broker.KcOidcBrokerParameterForwardTest

Sie können einen Test auch mit einem regulären Ausdruck mit -Dtest angeben. Mit dem folgenden Befehl können beispielsweise nur Identity Broker-bezogene Tests ausgeführt werden.

$ mvn -f testsuite/integration-arquillian/tests/base/pom.xml test -Dtest=org.keycloak.testsuite.broker.Kc*

Dieser Basistest war nur ein grundlegender Funktionstest, es werden jedoch verschiedene Tests wie Adaptertest und UI-Test implementiert. Weitere Informationen finden Sie unter [HOW-TO-RUN.md](https://github.com/keycloak/keycloak/blob/master/testsuite/integration-arquillian/HOW-TO-RUN. Im Projekt "keycloak-testsuite". Siehe md).

Damit sind die erforderlichen Codeänderungen abgeschlossen. Ich werde das Update endlich auf GitHub veröffentlichen.

Poste auf GitHub

Schieben Sie den geänderten Code an GitHub und stellen Sie eine Pull-Anfrage. TravisCI führt den Integrationstest aus. Es dauert ungefähr 20 Minuten, um alle Tests abzuschließen. Wenn alle Tests bestanden wurden, werden sie überprüft.

Die Codeüberprüfung wurde gut angesehen (assertThat ist einfacher zu lesen als assertTrue / assertFalse usw.). Zuerst habe ich einen Komponententest geschrieben, aber da die Funktion bereits durch den Integrationstest abgedeckt war, erhielt ich den Kommentar "Wenn der Inhalt im Integrationstest und im Komponententest dupliziert wird, erhöhen sich die Wartungskosten" und entschied, dass dies nicht erforderlich ist. wurde.

Es scheint, dass die Richtlinie lautet, dass Unit-Tests nicht erforderlich sind, wenn sie abgedeckt werden können, da der Integrationstest solide ist.

Mir wurde gesagt, dass die Änderungen irgendwann zu einem Commit kombiniert werden würden, also kombinierte ich die Commits mit "git rebase -i" und drückte mit "git push -f".

Das Zusammenführen dauerte eine Weile, wurde jedoch erfolgreich zusammengeführt. https://github.com/keycloak/keycloak/pull/5163

Zusammenfassung

Keycloak ist in der Community aktiv, neue Funktionen werden nacheinander entwickelt und Verbesserungen von außerhalb der Community werden aktiv integriert.

Lassen Sie uns immer mehr Patches aus Japan veröffentlichen und daraus ein gutes OSS machen.

Recommended Posts

Einführung in die Keycloak-Entwicklung
Einführung in die Android App-Entwicklung
Einführung in Ruby 2
Einführung in web3j
Einführung in Micronaut 1 ~ Einführung ~
[Java] Einführung in Java
Einführung in die Migration
Einführung in Java
Einführung in Doma
Einführung in Slay the Spire Mod Development (1) Einführung
Einführung in die praktische Containerentwicklung von Docker / Kubernetes
Einführung in JAR-Dateien
Einführung in Ratpack (8) -Session
Einführung in die Bitarithmetik
Einführung in Ratpack (9) - Thymeleaf
Einführung in das Android-Layout
Einführung in Entwurfsmuster (Einführung)
Einführung in die praktische Programmierung
Einführung in den Befehl javadoc
Einführung in den Befehl jar
Einführung in Ratpack (2) -Architektur
Einführung in den Java-Befehl
Einführung in den Roboterkampf mit Robocode (Anfängerentwicklung)
Einführung in den Befehl javac
Einführung in Slay the Spire Mod Development (2) Konstruktion der Entwicklungsumgebung
[Einführung in die Android App-Entwicklung] Machen wir einen Zähler
Einführung in Entwurfsmuster (Builder)
Einführung in Ratpack (5) --Json & Registry
Einführung in Metabase ~ Umgebungskonstruktion ~
Einführung in Ratpack (7) - Guice & Spring
Einführung in Entwurfsmuster (Composite)
Einführung in Micronaut 2 ~ Unit Test ~
Einführung in JUnit (Studiennotiz)
Einführung in Spring Boot ~ ~ DI ~
Einführung in Designmuster (Fliegengewicht)
[Java] Einführung in den Lambda-Ausdruck
Einführung in Spring Boot ② ~ AOP ~
Einführung in Apache Beam (2) ~ ParDo ~
Einführung in die EHRbase 2-REST-API
Einführung in Entwurfsmuster Prototyp
[Java] Einführung in die Stream-API
Einführung in Entwurfsmuster (Iterator)
Einführung in Spring Boot Teil 1
Einführung in Ratpack (1) - Was ist Ratpack?
Einführung in Entwurfsmuster (Strategie)
[Einführung in Janken (ähnliche) Spiele] Java
Einführung in die Entwicklung der Spire Mod-Entwicklung (3) Definition der Originalkarte
[Einführung in Java] Über Lambda-Ausdrücke
Einführung in Algorithmen mit Java-kumulativer Summe
Einführung in die funktionale Programmierung (Java, Javascript)