Dernière modification : Dec 08 , 2024

Objectifs

Ce tutoriel vous guidera à travers les étapes pour configurer RabbitMQ en tant que conteneur Docker et l'intégrer avec une application Quarkus afin d'envoyer et recevoir des événements de type "Nouvelle adoption disponible" et "Adoption finalisée".

Prérequis

Pour compléter ce guide, vous aurez besoin de :

  • Environ 15 minutes
  • Un IDE
  • JDK 17+ installé avec JAVA_HOME configuré correctement
  • Apache Maven 3.9.6
  • Un environnement d'exécution de conteneur fonctionnel (Docker ou Podman)
  • Facultativement, le CLI Quarkus si vous souhaitez l'utiliser
  • Facultativement, Mandrel ou GraalVM installés et configurés correctement si vous souhaitez construire un exécutable natif (ou Docker si vous utilisez une construction de conteneur natif)
  • L'outil de traitement en ligne de commande jq

Contenu

Une partie de ce cours reprend directement le tutoriel Quarkus et OIDC.

Architecture

Cet exemple montre comment vous pouvez construire un microservice simple offrant deux endpoints :

/api/users/me
/api/admin

Ces endpoints sont protégés et ne peuvent être accédés que si un client envoie un jeton Bearer avec la requête, qui doit être valide (par exemple, signature, expiration, et audience) et de confiance pour le microservice.

Un serveur Keycloak émet le jeton Bearer et représente le sujet pour lequel le jeton a été émis. Étant un serveur d'autorisation OAuth 2.0, le jeton fait également référence au client agissant au nom de l'utilisateur.

Tout utilisateur avec un jeton valide peut accéder au endpoint /api/users/me. En réponse, il retourne un document JSON avec les détails de l'utilisateur obtenus à partir des informations du jeton.

Le endpoint /api/admin est protégé par RBAC (Contrôle d'accès basé sur les rôles), auquel seuls les utilisateurs avec le rôle admin peuvent accéder. À ce endpoint, l'annotation @RolesAllowed est utilisée pour appliquer la contrainte d'accès de manière déclarative. Solution

Suivez les instructions des sections suivantes et créez l'application étape par étape. Vous pouvez également aller directement à l'exemple complet.

Créer le projet Maven

Vous pouvez soit créer un nouveau projet Maven avec l'extension oidc, soit ajouter l'extension à un projet Maven existant. Complétez l'une des commandes suivantes :

Pour créer un nouveau projet Maven, utilisez la commande suivante :

CLI


quarkus create app org.acme:security-openid-connect-quickstart \
 --extension='oidc,rest-jackson' \
 --no-code
cd security-openid-connect-quickstart

Maven


mvn io.quarkus.platform:quarkus-maven-plugin:3.10.2:create \
 -DprojectGroupId=org.acme \
 -DprojectArtifactId=security-openid-connect-quickstart \
 -Dextensions='oidc,rest-jackson' \
 -DnoCode
cd security-openid-connect-quickstart

Pour les utilisateurs Windows :

  • Si vous utilisez cmd, (ne pas utiliser de barre oblique \ et mettre tout sur la même ligne)
  • Si vous utilisez Powershell, mettez les paramètres -D entre guillemets, par exemple ""-DprojectArtifactId=security-openid-connect-quickstart""

Si vous avez déjà configuré votre projet Quarkus, vous pouvez ajouter l'extension oidc à votre projet en exécutant la commande suivante dans le répertoire de base de votre projet :

CLI :


quarkus extension add oidc

Maven :


./mvnw quarkus:add-extension -Dextensions='oidc'

Cela ajoutera les dépendances suivantes à votre fichier de build :

pom.xml :


<dependency>
   <groupId>io.quarkus</groupId>
   <artifactId>quarkus-oidc</artifactId>
</dependency>

Écrire l'application

Implémentez le endpoint /api/users/me comme indiqué dans l'exemple suivant, qui est une ressource REST Jakarta régulière :


package org.acme.security.openid.connect;

import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

import org.jboss.resteasy.reactive.NoCache;
import io.quarkus.security.identity.SecurityIdentity;

@Path("/api/users")
public class UsersResource {

    @Inject
    SecurityIdentity securityIdentity;

    @GET
    @Path("/me")
    @RolesAllowed("user")
    @NoCache
    public User me() {
        return new User(securityIdentity);
    }

    public static class User {

        private final String userName;

        User(SecurityIdentity securityIdentity) {
            this.userName = securityIdentity.getPrincipal().getName();
        }

        public String getUserName() {
            return userName;
        }
    }

}

Implémentez le endpoint /api/admin comme indiqué dans l'exemple suivant :


package org.acme.security.openid.connect;

import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/api/admin")
public class AdminResource {

    @GET
    @RolesAllowed("admin")
    @Produces(MediaType.TEXT_PLAIN)
    public String admin() {
        return "granted";
    }

}

La principale différence dans cet exemple est que l'annotation @RolesAllowed est utilisée pour vérifier que seuls les utilisateurs ayant le rôle admin peuvent accéder au endpoint.

L'injection de SecurityIdentity est supportée dans les contextes @RequestScoped et @ApplicationScoped.

Configurer l'application

Configurez l'extension OpenID Connect (OIDC) de Quarkus en définissant les propriétés de configuration suivantes dans le fichier src/main/resources/application.properties :


quarkus.oidc.auth-server-url=http://localhost:8180/realms/master
quarkus.oidc.client-id=backend-service
quarkus.oidc.credentials.secret=secret

Demandez à Dev Services for Keycloak d'importer le fichier de realm

Cette propriété n'est pas effective lors de l'exécution de l'application en modes JVM ou natif

quarkus.keycloak.devservices.realm-path=quarkus-realm.json

Démarrer et configurer le serveur Keycloak

Télécharger le realm d'exemple à l'adresse suivante.

Placez le fichier de configuration de realm sur le classpath (répertoire target/classes) ou dans src/main/resources.

Pour démarrer un serveur Keycloak, utilisez Docker pour exécuter la commande suivante :


docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:latest start-dev

Accédez à votre serveur Keycloak à l'adresse http://localhost:8180.

Connectez-vous à la console d'administration Keycloak avec les identifiants suivants :

Nom d'utilisateur : admin
Mot de passe : admin

Importez le fichier de configuration de realm pour créer un nouveau realm.

Exécuter l'application en mode dev

Pour exécuter l'application en mode dev, exécutez les commandes suivantes :

CLI :


quarkus dev

Maven :


./mvnw quarkus:dev

Ouvrez l'interface utilisateur Dev, que vous pouvez trouver à /q/dev-ui. Ensuite, dans une carte OpenID Connect, cliquez sur le lien Keycloak provider.

Lorsque vous êtes invité à vous connecter à une Single Page Application fournie par OpenID Connect Dev UI, faites les étapes suivantes :

  • Connectez-vous en tant que alice (mot de passe : alice), qui a un rôle user.

  • Accéder à /api/admin renvoie un code d'état 401.

  • Accéder à /api/users/me: renvoie un code _401.

  • Ouvrez l'interface utilisateur Dev, que vous pouvez trouver à /q/dev-ui. Ensuite, dans une OpenID Connect Card, cliquez sur le lien Keycloak provider.

Lorsque vous êtes invité à vous connecter à une Single Page Application fournie par OpenID Connect Dev UI, faites les étapes suivantes :

  • Connectez-vous en tant que alice (mot de passe : alice), qui a un rôle user.
    • Accéder à /api/admin renvoie un code d'état 403.
    • Accéder à /api/users/me renvoie la traduction de l'intégralité du guide sur l'authentification par jeton Bearer OIDC pour Quarkus :
  • Protéger une application de service avec l'authentification par jeton Bearer OpenID Connect (OIDC)

Utilisez l'extension OpenID Connect (OIDC) de Quarkus pour sécuriser une application REST Jakarta avec l'authentification par jeton Bearer. Les jetons Bearer sont émis par des serveurs d'autorisation compatibles OIDC et OAuth 2.0, comme Keycloak.

Pour plus d'informations sur l'authentification par jeton Bearer OIDC, consultez le guide OIDC Bearer token authentication de Quarkus.

Définitions

Voici une liste de définitions à se rappeler pour la partie authentification.

Bearer Token

Un token Bearer est un type de jeton d'accès utilisé dans les protocoles d'autorisation OAuth 2.0 et OpenID Connect (OIDC). Il s'agit d'une chaîne de caractères opaque qui représente l'autorisation d'un client à accéder à une ressource protégée.

Caractéristiques principales d'un token Bearer:

  • Opaque: Le contenu du token n'est pas lisible par le client.

  • Auto-contenu: Le token contient toutes les informations nécessaires pour autoriser l'accès à la ressource, telles que l'identité du client, les scopes d'accès et l'expiration du token.

  • Transférable: Le token peut être transféré entre différents clients, à condition qu'ils aient tous les deux accès à la ressource protégée.

  • Court-durée: Les tokens Bearer ont généralement une durée de vie limitée, ce qui permet de limiter les risques de sécurité. Fonctionnement d'un token Bearer:

  • Le client s'authentifie auprès du serveur d'autorisation et obtient un token Bearer.

  • Le client inclut le token Bearer dans l'en-tête d'autorisation de chaque requête à la ressource protégée.

  • Le serveur de ressources valide le token Bearer et autorise l'accès à la ressource si le token est valide.

Avantages d'un token Bearer:

  • Sécurité: Les tokens Bearer sont plus sûrs que les autres types de jetons d'accès, car ils ne contiennent pas d'informations sensibles.
  • Simplicité: Les tokens Bearer sont faciles à utiliser et à gérer.
  • Flexibilité: Les tokens Bearer peuvent être utilisés avec différents protocoles d'autorisation.

Exemples d'utilisation de tokens Bearer:

  • API REST: Les tokens Bearer sont souvent utilisés pour sécuriser les API REST.
  • Applications web: Les tokens Bearer peuvent être utilisés pour sécuriser les applications web.
  • Applications mobiles: Les tokens Bearer peuvent être utilisés pour sécuriser les applications mobiles.

En résumé, un token Bearer est un type de jeton d'accès sécurisé et flexible qui est largement utilisé dans les protocoles d'autorisation OAuth 2.0 et OIDC.

Realm

Un Realm est un espace de noms logique dans Keycloak qui représente un ensemble d'utilisateurs, de clients, de rôles et de ressources. Il s'agit d'une unité d'administration et d'isolation dans Keycloak, permettant de gérer de manière indépendante plusieurs groupes d'utilisateurs et d'applications.

Client ID

Caractéristiques principales d'un Realm:

  • Espace de noms unique: Chaque Realm possède un nom unique qui le distingue des autres Realms dans Keycloak.
  • Gestion des utilisateurs: Un Realm contient des utilisateurs, des groupes et des rôles qui peuvent être utilisés pour contrôler l'accès aux ressources.
  • Gestion des clients: Un Realm peut enregistrer des clients, tels que des applications web, des applications mobiles ou des API, qui peuvent demander l'accès aux ressources protégées.
  • Gestion des ressources: Un Realm peut définir des ressources, telles que des API ou des pages web, qui peuvent être protégées par l'authentification et l'autorisation.
  • Isolation: Les Realms sont isolés les uns des autres, ce qui signifie que les utilisateurs, les clients et les ressources d'un Realm ne sont pas accessibles aux autres Realms.
  • Configuration: Chaque Realm peut avoir sa propre configuration, y compris les paramètres d'authentification, les politiques d'autorisation et les flux de travail.

En résumé, un Realm est un concept important dans Keycloak qui permet de gérer et d'isoler les utilisateurs, les clients et les ressources de manière efficace et sécurisée.

Client Secret

Un Client Secret est une chaîne de caractères secrète utilisée par un client OAuth 2.0 pour s'authentifier auprès d'un serveur d'autorisation. Il est généralement associé à un Client ID, qui est un identifiant public du client.

OpenID Connect

OpenID Connect (OIDC) est un protocole d'authentification basé sur OAuth 2.0 qui permet aux clients de vérifier l'identité d'un utilisateur et d'obtenir des informations de base sur cet utilisateur auprès d'un fournisseur d'identité (IdP). Il s'agit d'une couche d'identité au-dessus d'OAuth 2.0 qui fournit des informations d'identité standardisées.

Keycloak

Keycloak est un serveur d'identité open-source et un fournisseur d'accès unique (SSO) qui permet aux applications de gérer l'authentification et l'autorisation des utilisateurs. Il est basé sur les protocoles OAuth 2.0 et OpenID Connect (OIDC) et offre une variété de fonctionnalités, notamment :

Keycloak Dev Services

Keycloak Dev Services est un outil qui permet de démarrer et de configurer facilement un serveur Keycloak en mode développement. Il est intégré à Quarkus et permet de simplifier la configuration et l'utilisation de Keycloak pour les développeurs Quarkus.

Utilisation de Keycloak Dev Services :

Pour utiliser Keycloak Dev Services, vous devez ajouter la dépendance quarkus-keycloak-devservices à votre projet Quarkus. Ensuite, vous devez configurer Keycloak Dev Services dans votre fichier application.properties.

Exemple de configuration de Keycloak Dev Services

quarkus.keycloak.devservices.enabled=true
quarkus.keycloak.devservices.realm-path=quarkus-realm.json

Remarques

  • Keycloak Dev Services est uniquement disponible en mode développement.
  • Keycloak Dev Services ne doit pas être utilisé en production.

En résumé, Keycloak Dev Services est un outil puissant et facile à utiliser qui permet aux développeurs Quarkus de simplifier la configuration et l'utilisation de Keycloak.