[JAVA] Introduction au développement de Keycloak

Première édition: 2018/8/1

Auteur: Koji Mogi, Hitachi, Ltd.

introduction

Keycloak (https://www.keycloak.org/) est un logiciel de gestion d'accès d'identité open source. N'importe qui peut contribuer au développement de Keycloak car il est développé sur une base communautaire, mais je pense qu'il est difficile de se lancer sans connaître la méthode de développement et les règles de la communauté. Donc, cette fois, j'aimerais partager les connaissances que j'ai acquises à travers le contenu du développement du patch (# 5163) que j'ai fait. ..

Ces informations peuvent être trouvées dans README.md et HackingOnKeycloak.md dans le référentiel Keycloak. 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) est la base.

Cet article est un ajout au contenu présenté à OSS Security Technology Association 3rd Study Group.

table des matières

Ce qui a été développé

Keycloak a une fonction appelée Courtage d'identité, et le résultat de l'authentification avec un fournisseur OpenID Connect externe peut être utilisé avec Keycloak. Keycloak dispose également de paramètres pour se connecter à des fournisseurs populaires tels que Google et Facebook.

brokering.png

Puisqu'il était nécessaire que le processus d'authentification de l'utilisateur, y compris l'écran, soit effectué par nous-mêmes, nous l'avons configuré pour rediriger vers notre propre application d'authentification à l'aide du courtage d'identité. Cependant, dans cette application d'authentification, il était nécessaire que le client envoie des paramètres en dehors des spécifications d'OpenID Connect, mais dans Keycloak's Identity Brokering, le paramètre de requête que vous souhaitez spécifier indépendamment est transféré au fournisseur d'identité externe (= écran d'authentification). pas.

Pour résoudre ce problème, nous avons implémenté notre propre fournisseur d'identité qui transfère les paramètres à l'aide du fournisseur d'identité SPI (une interface pour étendre le courtage d'identité). Cependant, j'ai senti qu'il y avait d'autres cas d'utilisation qui utilisaient des paramètres en dehors de la spécification OpenID Connect, j'ai donc décidé de contribuer à la communauté en tant que fonction générale.

Suggestions de fonctionnalités, rapports de bogues

Keycloak utilise les outils suivants pour proposer de nouvelles fonctionnalités et signaler des bogues.

Si vous trouvez un bogue, créez d'abord un ticket avec des détails dans JIRA, puis créez une Pull Request avec l'ID du ticket dans le titre.

À partir de là, nous présenterons comment préparer l'environnement de développement du correctif, comment changer le code, comment exécuter le test, etc. en fonction de la connaissance du développement réel du correctif.

Préparation à la mise en œuvre

Commencez par bifurquer le référentiel Keycloak et cloner le référentiel.

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

Nous préparerons dans ce répertoire cloné.

Comment construire

Lorsque vous apportez le code source, créez-le d'abord. JDK et Maven sont requis pour la construction, veuillez donc les configurer chacun.

Créez le code source avec la commande suivante.

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

Les tests peuvent échouer en fonction de l'environnement, c'est donc une bonne idée d'ignorer les tests au moment de la construction, de les corriger, puis d'exécuter uniquement les tests pertinents. Lorsque la commande ci-dessus est exécutée, la construction (.tar.gz, .zip) sera sortie sous distribution / server-dist / target. Vous pouvez également lancer Keycloak en les décompressant et en exécutant bin / standalone.sh.

Importer dans l'IDE

Ensuite, nous préparerons le développement avec IDE. Cette fois, j'ai utilisé Eclipse (Oxygen) comme IDE. Importez le projet Maven dans Eclipse en spécifiant le fichier pom.xml (qui sera le projet keycloak-parent) directement sous le référentiel Keycloak.

En raison du grand nombre de projets (300+), l'importation prendra un certain temps.

Comment déboguer avec IDE (Eclipse)

Pour démarrer Keycloak en cours de développement, exécutez mvn -f testsuite / utils / pom.xml exec: java -Pkeycloak-server comme décrit dans README.md. Après avoir démarré le serveur Keycloak, vous pouvez accéder à l'interface graphique de Keycloak depuis localhost: 8081 / auth /.

Comme mentionné ci-dessus, il est possible de l'exécuter avec Maven depuis la ligne de commande, mais puisque nous utilisons Eclipse, nous pourrons y déboguer. En regardant le pom.xml spécifié dans la commande ci-dessus, la classe ʻorg.keycloak.testsuite.KeycloakServer du projet keycloak-testsuite-utils` est exécutée, spécifiez donc cette classe pour le débogage. Éxécuter. Les paramètres sont indiqués dans la figure ci-dessous.

debug_config.png

Vous pouvez maintenant utiliser Eclipse pour déboguer Keycloak.

Configurez davantage les paramètres de la base de données. InMemoryDB de H2DB est utilisé par défaut, mais s'il est laissé tel quel, le paramètre sera supprimé à chaque redémarrage. Puisqu'il est difficile de le réinitialiser plusieurs fois, configurez-le pour l'enregistrer dans un fichier. Spécifiez -Dkeycloak.connectionsJpa.url = jdbc: h2: ./keycloak; AUTO_SERVER = TRUE comme argument de démarrage. La méthode de réglage dans Eclipse est illustrée dans la figure ci-dessous.

persist_settings.png

Maintenant que nous sommes prêts pour le développement, y compris le débogage, nous allons modifier le code.

Correction de code

De là, nous expliquerons l'architecture simple de Keycloak basée sur le contenu qui implémente la fonction "Transférer des paramètres personnalisés vers un fournisseur d'identité externe avec la fonction de courtage d'identité".

Détails de la correction

Les valeurs des paramètres lors de l'accès au point de terminaison d'autorisation Keycloak étaient stockées dans un modèle appelé AuthorizationSession, y compris les paramètres non spécifiés. Ainsi, dans la partie qui crée la RedirectURL vers le fournisseur d'identité externe, je l'ai modifiée pour obtenir les paramètres de non-spécification de la session d'autorisation et les ajouter à l'URL.

De plus, au lieu de transmettre tous les paramètres, seuls les paramètres spécifiés dans les paramètres de courtage d'identité sont transférés.

Emplacement des fichiers associés au fournisseur d'identité

Les fonctions de base telles que l'authentification et l'autorisation, et les fonctions de courtage d'identité sont implémentées dans un projet appelé «keycloak-services». Ce projet implémente le SPI défini par keycloak-spi, keycloak-spi-private. Comme dans le cas du développement d'un plug-in à l'aide de SPI, «Provider» et «ProviderFactory» sont implémentés par paires.

Le fournisseur d'identité OpenID Connect est implémenté dans une classe appelée «org.keycloak.broker.oidc.OIDCIdentityProvider». L'URL de redirection vers le fournisseur d'identité externe a été créée par la méthode createAuthorizationUrl de ʻorg.keycloak.broker.oidc.AbstractOauth2IdentityProvider` héritée par cette classe, j'ai donc modifié cette méthode. C'était.

Modifications de l'interface graphique

Afin de ne transférer que des paramètres externes spécifiques, un élément pour définir les paramètres à transférer a été ajouté à l'élément de réglage du fournisseur d'identité.

label.png

L'interface graphique de Keycloak est réalisée avec AngularJS (1.6). Vous pouvez trouver le template et le code Javascript sous le keycloak-themes du projet. Étant donné que les éléments de configuration du fournisseur d'identité ont été conçus pour envoyer tout le contenu du formulaire à l'API, il pourrait être implémenté simplement en ajoutant le formulaire et l'info-bulle au modèle realm-identity-provider-oidc.html.

Depuis juillet 2018, un dossier appelé keycloak-preview a été créé sous keycloak-themes. Il semble que l'interface graphique de la console d'administration de Keycloak soit nouvellement créée, et quand je l'ai regardée à la légère, il semblait qu'elle avait été créée avec Angular 5. J'ai vu des pull requests telles que le support réactif, donc j'aimerais m'attendre et attendre.

Modification du schéma de base de données

Depuis que j'ai augmenté les éléments de configuration du fournisseur d'identité, j'ai pensé qu'il était nécessaire de changer le schéma de base de données. Cependant, comme les éléments de paramétrage étaient enregistrés dans la table ʻIDENTITY_PROVIDER_CONFIGsous la forme de valeur-clé, il n'était pas nécessaire de modifier le schéma. Il est également géré parMap <String, String>` dans le code. Étant donné qu'il y a de nombreux changements dans les éléments de réglage, j'ai pensé qu'il était rationnel de faire cela afin qu'il puisse être géré sans avoir besoin de changements de schéma.

Je n'ai pas eu besoin de changer le schéma cette fois, mais si je dois apporter des modifications liées à la base de données, je les changerai car les modèles sont organisés dans le projet keycloak-model-jpa.

Mise en œuvre des tests

Keycloak utilise un framework de test appelé Arquiilian pour effectuer des tests d'intégration. Les tests de courtage d'identité sont inclus dans un projet appelé ʻintegration-arquiilian-tests-base (testsuite \ integration-arquillian \ tests \ base`).

Quant à la façon de tester le fournisseur d'identité externe, il était pris en charge à l'aide de deux royaumes, «consommateur» et «fournisseur», comme indiqué sur la figure.

provider-consumer.png

En regardant les tests existants, il y avait un test qui vérifiait les paramètres de la requête, donc je l'ai utilisé pour décrire le test.

Pour exécuter le test implémenté, exécutez la commande suivante.

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

Cela exécutera les tests de fonctionnement de base, mais chaque test prendra beaucoup de temps, et en raison du nombre de tests, il faudra un temps considérable pour terminer tous les tests. Pour exécuter un test spécifique, spécifiez le nom de la classe avec -Dtest.

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

Vous pouvez également spécifier un test en utilisant une expression régulière avec -Dtest. Par exemple, la commande suivante ne peut exécuter que des tests liés à Identity Broker.

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

Ce test de base n'était qu'un test de fonctionnement de base, mais divers tests tels que le test d'adaptateur et le test d'interface utilisateur sont mis en œuvre. Pour plus d'informations, consultez [HOW-TO-RUN.md](https://github.com/keycloak/keycloak/blob/master/testsuite/integration-arquillian/HOW-TO-RUN.dans le projet keycloak-testsuite. Voir md).

Ceci complète les modifications de code nécessaires. Je vais enfin publier le correctif sur GitHub.

Publier sur GitHub

Envoyez le code modifié sur GitHub et émettez une Pull Request pour exécuter le test d'intégration dans TravisCI. Il faut environ 20 minutes pour terminer tous les tests. Si tous les tests réussissent, ils seront examinés.

La revue de code a été bien vue (assertThat est plus facile à lire que assertTrue / assertFalse, etc.). Au début, j'ai écrit un test unitaire, mais comme la fonction était déjà couverte par le test d'intégration, j'ai reçu un commentaire disant que "Si le contenu est dupliqué dans le test d'intégration et le test unitaire, le coût de maintenance augmentera" et j'ai décidé que ce n'était pas nécessaire. devenu.

Il semble que la politique est que les tests unitaires ne sont pas nécessaires s'ils peuvent être couverts car le test d'intégration est solide.

On m'a dit que les changements seraient finalement combinés en un seul commit, donc j'ai combiné les commits avec git rebase -i et poussé avec git push -f.

La fusion a pris un certain temps, mais elle a été fusionnée avec succès. https://github.com/keycloak/keycloak/pull/5163

Résumé

Keycloak est actif dans la communauté, de nouvelles fonctionnalités sont développées les unes après les autres et nous intégrons activement des améliorations venant de l'extérieur de la communauté.

Sortons de plus en plus de correctifs du Japon et faisons-en un bon OSS.

Recommended Posts

Introduction au développement de Keycloak
Introduction au développement d'applications Android
Introduction à Ruby 2
Introduction à web3j
Introduction à Micronaut 1 ~ Introduction ~
[Java] Introduction à Java
Introduction à la migration
Introduction à Java
Introduction à Doma
Introduction au développement du mod Slay the Spire (1) Introduction
Introduction au développement pratique de conteneurs Docker / Kubernetes
Introduction aux fichiers JAR
Introduction à Ratpack (8) - Session
Introduction à l'arithmétique des bits
Introduction à Ratpack (9) --Thymeleaf
Introduction à la mise en page Android
Introduction aux modèles de conception (introduction)
Introduction à la programmation pratique
Introduction à la commande javadoc
Introduction à la commande jar
Introduction à Ratpack (2) -Architecture
Introduction à la commande java
Introduction à Robot Battle avec Robocode (développement pour débutants)
Introduction à la commande javac
Introduction au développement de modules Slay the Spire (2) Construction de l'environnement de développement
[Introduction au développement d'applications Android] Faisons un compteur
Introduction aux modèles de conception (Builder)
Introduction à Ratpack (5) --Json & Registry
Introduction à la métabase ~ Construction de l'environnement ~
Introduction à Ratpack (7) --Guice & Spring
Introduction aux modèles de conception (composite)
Introduction à Micronaut 2 ~ Test unitaire ~
Introduction à JUnit (note d'étude)
Introduction à Spring Boot ① ~ DI ~
Introduction aux modèles de conception (poids mouche)
[Java] Introduction à l'expression lambda
Introduction à Spring Boot ② ~ AOP ~
Introduction à Apache Beam (2) ~ ParDo ~
Introduction à l'API EHRbase 2-REST
Introduction au prototype de modèles de conception
[Java] Introduction à l'API Stream
Introduction aux modèles de conception (Iterator)
Introduction à Spring Boot, partie 1
Introduction à Ratpack (1) - Qu'est-ce que Ratpack?
Introduction aux modèles de conception (stratégie)
[Introduction aux jeux Janken (comme)] Java
Introduction au développement du mod Slay the Spire (3) Définition de la carte originale
[Introduction à Java] À propos des expressions lambda
Introduction aux algorithmes avec somme cumulée Java
Introduction à la programmation fonctionnelle (Java, Javascript)