Construire un microservice JHipster de base sécurisé par UAA

1. Vue d’ensemble

Dans les articles précédents, nous avons abordé les basics et comment l’utiliser pour générer un microservices-based application .

Dans ce didacticiel, nous allons explorer le service de compte d’utilisateur et d’autorisation de JHipster , en abrégé UAA, et comment l’utiliser pour sécuriser une application complète de microservice basée sur JHispter. Mieux encore, tout cela peut être réalisé sans écrire une seule ligne de code !

2. Fonctionnalités UAA Core

Une caractéristique importante des applications que nous avons créées dans nos articles précédents est que les comptes d’utilisateurs en font partie intégrante. Cela n’est pas un problème si nous n’avons qu’une seule application, mais que faire si nous voulons partager des comptes d’utilisateur entre plusieurs applications générées par JHipster? C’est là que la solution UAA de JHipster entre en jeu.

La solution UAA de JHipster est un microservice construit, déployé et exécuté indépendamment des autres services de notre application . Il sert comme:

  • Un serveur d’autorisation OAuth2, basé sur l’implémentation de Spring Boot

  • Un serveur d’identité, exposant un compte utilisateur API CRUD

JHipster UAA prend également en charge les fonctionnalités de connexion classiques, telles que l’auto-inscription et «Remember me». Et bien sûr, il s’intègre parfaitement à d’autres services JHipster.

3. Configuration de l’environnement de développement

Avant de commencer tout développement, nous devons d’abord nous assurer que notre environnement dispose de toutes les conditions préalables. Outre tous les outils décrits dans notre article Intro To JHipster , nous avons besoin d’un registre JHipster en cours d’exécution. Tout comme une récapitulation rapide, le service de registre permet aux différents services que nous allons créer de se retrouver et de se parler.

La procédure complète pour générer et exécuter le registre est décrite à la section 4.1 de notre JHipster avec un article sur Microservice Architecture , nous ne le répéterons donc pas ici. Une image Docker est également disponible et peut également être utilisée.

4. Génération d’un nouveau service JHipster UAA

Générons notre service UAA à l’aide de l’utilitaire de ligne de commande JHipster:

$ mkdir uaa
$ cd uaa
$ jhipster

La première question à laquelle nous devons répondre est quel type d’application nous voulons générer. A l’aide des touches fléchées, nous allons sélectionner l’option «JHipster UAA (pour l’authentification de microservice OAuth2)»:

Nous allons ensuite répondre à quelques questions concernant des détails spécifiques concernant le service généré, telles que le nom de l’application, le port du serveur et la découverte du service:

Dans la plupart des cas, les réponses par défaut sont correctes. En ce qui concerne le nom de base de l’application , qui affecte de nombreux artefacts générés , nous avons choisi «uaa» (minuscule) - un nom raisonnable. Nous pouvons jouer avec les autres valeurs si nous le souhaitons, mais cela ne changera pas les caractéristiques principales du projet généré.

Après avoir répondu à ces questions, JHipster créera tous les fichiers de projet et installera les dépendances de paquets npm (qui ne sont pas vraiment utilisées dans ce cas).

Nous pouvons maintenant utiliser le script Maven local pour créer et exécuter notre service UAA:

$ ./mvnw
... build messages omitted
2018-10-14 14:07:17.995  INFO 18052 ---[ restartedMain]com.baeldung.jhipster.uaa.UaaApp         :
----------------------------------------------------------
        Application 'uaa' is running! Access URLs:
        Local:          http://localhost:9999/        External:       http://192.168.99.1:9999/        Profile(s):    [dev, swagger]----------------------------------------------------------
2018-10-14 14:07:18.000  INFO 18052 ---[ restartedMain]com.baeldung.jhipster.uaa.UaaApp         :
----------------------------------------------------------
        Config Server:  Connected to the JHipster Registry config server!
----------------------------------------------------------
  • Le message clé à retenir ici est celui indiquant que UAA est connecté au registre JHipster. ** Ce message indique que UAA a pu s’inscrire et sera disponible pour la découverte par d’autres microservices et passerelles.

5. Test du service UAA

Étant donné que le service UAA généré ne possède pas d’interface utilisateur, nous devons utiliser des appels d’API directs pour vérifier s’il fonctionne comme prévu.

  • Nous devons nous assurer que deux fonctionnalités sont disponibles avant de l’utiliser avec d’autres composants ou avec notre système: ** Génération de jetons OAuth2 et récupération de compte.

Commençons par obtenir un nouveau jeton à partir du point de terminaison OAuth de notre UAA, à l’aide d’une simple commande curl

$ curl -X POST --data \
 "username=user&password=user&grant__type=password&scope=openid" \
 http://web__app:[email protected]:9999/oauth/token

Ici, nous avons utilisé __password grant __flow, en utilisant deux paires de références. Dans ce type de flux, nous envoyons les informations d’identification du client à l’aide de l’authentification HTTP de base, que nous encodons directement dans l’URL.

Les informations d’identification de l’utilisateur final sont envoyées dans le corps, à l’aide des paramètres de nom d’utilisateur et de mot de passe standard. Nous utilisons également le compte utilisateur nommé «utilisateur» , disponible par défaut dans le profil de test.

En supposant que nous ayons fourni tous les détails correctement, nous obtiendrons une réponse contenant un jeton d’accès et un jeton d’actualisation:

{
  "access__token" : "eyJh...(token omitted)",
  "token__type" : "bearer",
  "refresh__token" : "eyJ...(token omitted)",
  "expires__in" : 299,
  "scope" : "openid",
  "iat" : 1539650162,
  "jti" : "8066ab12-6e5e-4330-82d5-f51df16cd70f"
}

Nous pouvons maintenant ** utiliser le access token renvoyé pour obtenir des informations sur le compte associé à l’aide de la ressource account__, disponible dans le service UAA:

$ curl -H "Authorization: Bearer eyJh...(access token omitted)" \
 http://localhost:9999/api/account
{
  "id" : 4,
  "login" : "user",
  "firstName" : "User",
  "lastName" : "User",
  "email" : "[email protected]",
  "imageUrl" : "",
  "activated" : true,
  "langKey" : "en",
  "createdBy" : "system",
  "createdDate" : "2018-10-14T17:07:01.336Z",
  "lastModifiedBy" : "system",
  "lastModifiedDate" : null,
  "authorities" :["ROLE__USER"]}
  • Veuillez noter que nous devons émettre cette commande avant l’expiration du jeton d’accès ** . Par défaut, le service UAA émet des jetons valides pendant cinq minutes, ce qui est une valeur raisonnable pour la production.

Nous pouvons facilement modifier la durée de vie des jetons valides en modifiant le fichier application- <profil> .yml correspondant au profil sous lequel l’application est en cours d’exécution et en définissant le paramètre uaa.web-client-configuration.access-token-validité-en secondes clé.

Les fichiers de paramètres se trouvent dans le répertoire src/main/resources/config de notre projet UAA.

6. Génération de la passerelle activée par UAA

Maintenant que nous sommes convaincus que notre service et notre registre de services fonctionnent, créons un écosystème avec lequel ils peuvent interagir. À la fin, nous aurons ajouté:

  • Un frontal à base angulaire

  • Un back-end de microservice

  • Une passerelle API qui fait face à ces deux

Commençons par la passerelle, car c’est le service qui négociera avec UAA pour l’authentification. Il va héberger notre application frontale et acheminer les requêtes d’API vers d’autres microservices.

Une fois encore, nous allons utiliser l’outil de ligne de commande JHipster dans un répertoire nouvellement créé:

$ mkdir gateway
$ cd gateway
$ jhipster

Comme auparavant, nous devons répondre à quelques questions afin de générer le projet. Les plus importants sont les suivants:

  • Type d’application : doit être une «passerelle Microservices»

  • Nom de l’application: Nous utiliserons cette fois «passerelle».

  • Service discovery : sélectionnez «JHipster registry»

  • Type d’authentification: ** Il faut sélectionner "Authentification avec

Serveur JHipster UAA ”option ici UI Framework: Choisissons “Angular 6”

Une fois que JHipster a généré tous ses artefacts, nous pouvons construire et exécuter la passerelle avec le script d’encapsuleur Maven fourni:

$ ./mwnw
... many messages omitted
----------------------------------------------------------
        Application 'gateway' is running! Access URLs:
        Local:          http://localhost:8080/        External:       http://192.168.99.1:8080/        Profile(s):    [dev, swagger]----------------------------------------------------------
2018-10-15 23:46:43.011  INFO 21668 ---[ restartedMain]c.baeldung.jhipster.gateway.GatewayApp   :
----------------------------------------------------------
        Config Server:  Connected to the JHipster Registry config server!
----------------------------------------------------------

Avec le message ci-dessus, nous pouvons accéder à notre application en pointant notre navigateur sur http://localhost : 8080, qui devrait afficher la page d’accueil générée par défaut:

Continuons et connectons-nous à notre application en naviguant jusqu’à l’élément de menu Compte> Login . Nous allons utiliser les informations d’identification __admin/admin __as que JHipster crée automatiquement par défaut. Tout va bien, la page d’accueil affiche un message confirmant la réussite de la connexion:

Récapitulons ce qui s’est passé pour nous amener ici: d’abord, la passerelle a envoyé nos informations d’identification au point de terminaison du jeton OAuth2 d’UAA, qui les a validées et a généré une réponse contenant un jeton JWT d’actualisation et d’accès. La passerelle a ensuite pris ces jetons et les a renvoyés au navigateur sous forme de cookies.

Ensuite, l’interface angulaire appelée API /uaa/api/account , qui a de nouveau été transmise par la passerelle à UAA. Dans ce processus, la passerelle récupère le cookie contenant le jeton d’accès et utilise sa valeur pour ajouter un en-tête d’autorisation à la demande.

Si nécessaire, nous pouvons voir tous ces flux en détail en vérifiant les journaux UAA et Gateway. Nous pouvons également obtenir des données complètes au niveau fil en définissant le niveau d’enregistrement org.apache.http.wire sur DEBUG.

7. Génération d’un microservice activé par UAA

Maintenant que notre environnement d’application est opérationnel, il est temps de lui ajouter un microservice simple. Nous allons créer un microservice «cours», qui exposera une API REST complète nous permettant de créer, interroger, modifier et supprimer un ensemble de cours. Chaque devis n’aura que trois propriétés:

  • Le symbole commercial de la citation

  • Son prix, et

  • L’horodatage de la dernière transaction

Revenons à notre terminal et utilisons l’outil en ligne de commande de JHipster pour générer notre projet:

$ mkdir quotes
$ cd quotes
$ jhipster

Cette fois-ci, nous demanderons à JHipster de générer une application Microsoft, appelée "guillemets". Les questions ressemblent à celles auxquelles nous avons déjà répondu. Nous pouvons conserver les valeurs par défaut pour la plupart d’entre eux, à l’exception de ces trois:

  • Service Discovery: Sélectionnez «JHipster Registry» car nous sommes déjà en train de

l’utiliser dans notre architecture ** Path à l’application UAA: Puisque nous conservons tous les projets

sous le même dossier, ce sera ../uaa (à moins que nous n’ayons changé, bien sûr) ** Type d’authentification: Sélectionnez «Serveur JHipster UAA».

Voici à quoi ressemblera une séquence typique de réponses dans notre cas:

Une fois que JHipster a fini de générer le projet, nous pouvons le construire:

$ mvnw
... many, many messages omitted
----------------------------------------------------------
        Application 'quotes' is running! Access URLs:
        Local:          http://localhost:8081/        External:       http://192.168.99.1:8081/        Profile(s):    [dev, swagger]----------------------------------------------------------
2018-10-19 00:16:05.581  INFO 16092 ---[ restartedMain]com.baeldung.jhipster.quotes.QuotesApp   :
----------------------------------------------------------
        Config Server:  Connected to the JHipster Registry config server!
----------------------------------------------------------
... more messages omitted

Le message «Connecté au serveur de configuration du registre JHipster!» Est ce que nous recherchons ici. Sa présence nous indique que le microservice s’est inscrit au registre et que, de ce fait, la passerelle pourra acheminer les requêtes vers notre ressource "quotes" et les afficher sur une belle interface utilisateur, une fois que nous l’aurons créée. Comme nous utilisons une architecture de microservice, nous divisons cette tâche en deux parties:

  • Créer le service back-end de ressources «citations»

  • Créer l’interface utilisateur «guillemets» dans l’interface frontale (partie du projet de passerelle)

7.1. Ajout de la ressource Citations

Tout d’abord, nous devons nous assurer que l’application microservice de citations est arrêtée - nous pouvons appuyer sur CTRL-C sur la même fenêtre de console que celle utilisée précédemment pour l’exécuter.

Ajoutons maintenant une entité au projet en utilisant l’outil de JHipster. Cette fois, nous utiliserons la commande import-jdl , ce qui nous évitera le processus fastidieux et sujet aux erreurs de fournir tous les détails individuellement.

Pour plus d’informations sur le format JDL, veuillez vous reporter à la full référence JDL .

Ensuite, nous créons un fichier texte appelé quotes.jh contenant notre définition __Quote __entity ** , ainsi que des directives de génération de code:

entity Quote {
  symbol String required unique,
  price BigDecimal required,
  lastTrade ZonedDateTime required
}
dto Quote with mapstruct
paginate Quote with pagination
service Quote with serviceImpl
microservice Quote with quotes
filter Quote
clientRootFolder Quote with quotes

Nous pouvons maintenant importer cette définition d’entité dans notre projet:

$ jhipster import-jdl quotes.jh
  • Remarque: lors de l’importation, JHipster se plaindra d’un conflit lors de l’application des modifications au fichier master.xml . Nous pouvons choisir en toute sécurité l’option overwrite dans ce cas. **

Nous pouvons maintenant construire et exécuter à nouveau notre microservice à l’aide de _mvnw. Une fois qu’il est activé, nous pouvons vérifier que la passerelle sélectionne le nouvel itinéraire en accédant à la vue Gateway , disponible dans le menu Administration . Cette fois, nous pouvons voir qu’il existe une entrée pour la route “/quotes/ , qui _ montre que le backend est prêt à être utilisé par l’UI.

7.2. Ajout de l’interface utilisateur des citations

Enfin, générons l’interface utilisateur CRUD dans le projet de passerelle que nous utiliserons pour accéder à nos devis. Nous allons utiliser le même fichier JDL du projet de microservice «quotes» pour générer les composants de l’interface utilisateur et l’importer à l’aide de la commande import-jdl de JHipster:

$ jhipster import-jdl ../jhipster-quotes/quotes.jh
...messages omitted
? Overwrite webpack\webpack.dev.js? <b>y</b>
... messages omitted
Congratulations, JHipster execution is complete!

Lors de l’importation, JHipster vous demandera à quelques reprises les mesures à prendre concernant les fichiers en conflit. Dans notre cas, nous pouvons simplement écraser les ressources existantes, car nous n’avons procédé à aucune personnalisation.

Nous pouvons maintenant redémarrer la passerelle et voir ce que nous avons accompli. Dirigeons notre navigateur sur la passerelle à http://localhost : 8080[ http://localhost : 8080 ], en veillant à en actualiser le contenu. Le menu Entities devrait maintenant avoir une nouvelle entrée pour la ressource Quotes :

En cliquant sur cette option de menu, vous accédez à l’écran de liste Quotes :

Comme prévu, la liste est vide - nous n’avons encore ajouté aucune citation!

Essayons d’en ajouter un en cliquant sur le bouton «Créer un nouveau devis» en haut à droite de cet écran, ce qui nous amène au formulaire de création/modification:

Nous pouvons voir que le formulaire généré a toutes les fonctionnalités attendues:

  • Les champs obligatoires sont marqués d’un indicateur rouge qui passe au vert

une fois rempli ** Les champs date/heure et numériques utilisent des composants natifs pour faciliter le traitement des données.

entrée ** Nous pouvons annuler cette activité, ce qui laissera les données inchangées, ou sauvegardera

notre entité nouvelle ou modifiée

Après avoir rempli ce formulaire et cliqué sur _Save, vous verrez les résultats à l’écran de liste. Nous pouvons maintenant voir la nouvelle instance Quotes ___ dans la grille de données:

  • En tant qu’administrateur, nous avons également accès à l’élément de menu de l’API ** , qui nous conduit au portail de développeur des API Swagger standard. Dans cet écran, nous pouvons sélectionner l’une des API disponibles pour exercer:

  • __default: la propre API de __Gateway qui affiche les itinéraires disponibles

  • uaa : API de compte et d’utilisateur

  • __quotes: __Quotes API

8. Prochaines étapes

L’application que nous avons construite jusqu’à présent fonctionne comme prévu et constitue une base solide pour le développement ultérieur. Nous aurons certainement aussi besoin d’écrire du code personnalisé (ou beaucoup), en fonction de la complexité de nos besoins. Certains domaines qui nécessiteront probablement des travaux sont:

  • UI look and feel personnalisation: Ceci est généralement assez facile en raison de

la manière dont l’application frontale est structurée - nous pouvons aller très loin simplement en jouant avec CSS et en ajoutant des images ** Modifications dans le référentiel d’utilisateurs: Certaines organisations ont déjà une sorte

d’un référentiel d’utilisateurs interne (p. ex. un annuaire LDAP) - cela nécessitera changements sur le UAA, mais la partie agréable est que nous devons seulement le changer une fois que Finer autorisation grainée sur les entités: La sécurité standard

Le modèle utilisé par le back-end d’entité généré ne dispose d’aucun type de sécurité au niveau instance et/ou au niveau du champ ** . Il appartient au développeur d’ajouter ces restrictions au niveau approprié (API ou service, selon le cas).

Même avec ces remarques, l’utilisation d’un outil tel que JHispter peut être très utile lors du développement d’une nouvelle application. Il apportera une base solide et pourra conserver un bon niveau de cohérence dans notre base de code au fur et à mesure de l’évolution du système et des développeurs.

9. Conclusion

Dans cet article, nous avons montré comment utiliser JHispter pour créer une application opérationnelle basée sur une architecture de microservices et sur le serveur UH de JHipster. Nous y sommes parvenus sans écrire une seule ligne de code Java , ce qui est assez impressionnant.

Comme d’habitude, le code complet des projets présentés dans cet article est disponible dans notre répertoire GitHub .