• Contenu
  • Bas de page
logo ouidoulogo ouidoulogo ouidoulogo ouidou
  • Qui sommes-nous ?
  • Offres
    • 💻 Applications métier
    • 🤝 Collaboration des équipes
    • 🛡️ Sécurisation et optimisation du système d’information
    • 🔗 Transformation numérique
  • Expertises
    • 🖥️ Développement logiciel
    • ♾️ DevSecOps
    • ⚙️ Intégration de logiciels et négoce de licences
      • Atlassian : Jira, Confluence, Bitbucket…
      • Plateforme monday.com
      • GitLab
      • SonarQube
    • 📚​ Logiciel de CRM et de gestion
    • 🎨 UX/UI design
    • 🌐 Accessibilité Numérique
    • 🗂️​ Démarches simplifiées
    • 📝 Formations Atlassian
    • 🤖 L’intelligence artificielle au service de vos projets numériques
  • Références
  • Carrières
    • 🧐 Pourquoi rejoindre Ouidou ?
    • ✍🏻 Nous rejoindre
    • 👨‍💻 Rencontrer nos collaborateurs
    • 🚀 Grandir chez Ouidou
  • RSE
  • Ressources
    • 🗞️ Actualités
    • 🔍 Articles techniques
    • 📖 Livres blancs
    • 🎙️ Interviews Clients
Nous contacter
✕
Formations Atlassian certifiées Qualiopi avec Ouidou
Formations Atlassian certifiées Qualiopi avec Ouidou
18 septembre 2025
Ressources > Articles techniques > Keycloak : Connexion avec Angular

Keycloak : Connexion avec Angular

Écrit par Etienne R.

Dans cette seconde partie, nous allons mettre en place une application front avec Angular. Sur la page d’accueil nous aurons un lien nous invitant à nous connecter à un dashboard. Cette page sera accessible uniquement aux personnes connectées. Pour ce faire, nous allons utiliser une librairie Angular afin de nous mâcher le travail.

Remarque : libre à vous d’utiliser l’API de Keycloak nativement et sans passer par la mire d’authentification de Keycloak.

Création du client dédié

Dans l’administration de Keycloak, créez un nouveau client, en cliquant sur “Clients” puis sur le bouton “Create client”. Dans le sélecteur “Client type”, laissez la valeur “OpenID Connect” puis définissez un id quelconque dans le champ “Client ID” et validez en cliquant sur le bouton “Next”.

Création d'un nouveau client (partie 1)

Puis cliquez de nouveau sur le bouton “Next”. Dans les champs “Root URL”, “Valid redirect URIs” et “Web origins”, définissez l’URL de base par défaut d’Angular, c’est-à-dire “http://localhost:4200”. Dans le champ “Valid post logout redirect URIs” saisissez “http://localhost:4200/logout“ et cliquez sur le bouton “Save”.

Création d'un nouveau client (partie 13)

Test de connexion avec CURL

Avec l’utilisateur créé précédemment, on peut tester la récupération du token avec la requête CURL ci-dessous.

curl -s -X POST http://localhost:8080/realms/ouidou/protocol/openid-connect/token \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=password&username=felicie.tations@ouidou.fr&password=<password>&client_id=angular-ouidou" | jq

On récupère bien un “access_token” autrement dit, un JWT (JSON Web Token) avec les données de notre utilisateur (email, nom, rôles, etc…). Mais aussi d’autres informations intéressantes telles que le temps d’expiration en millisecondes du token mais également du token refresh (“refresh_token”).

Changer le temps du token

Par défaut, il est de 5 minutes (300 ms). Pour le changer, cliquez sur le client concerné puis sur l’onglet “Advanced”. Allez dans la partie “Access Token Lifespan”. Dans le menu déroulant, sélectionnez “Expires in” puis indiquez une valeur en minute(s), en heure(s) ou en jour(s) puis validez en cliquant sur le bouton “Save”.

Installation et configuration d’Angular

Au préalable, vérifiez que Node et NPM sont bien installés sur votre machine de développement.

$ node -v && npm -v
v22.13.1
10.9.2

Afin de lancer la commande d’installation suivante npx -p @angular/cli ng new angular-ouidou.

Remarque : la version d’Angular utilisée lors de la rédaction de cet article est la 19.1.

Puis placez-vous dans le répertoire de l’application Angular afin d’y installer les 2 librairies supplémentaires “keycloak-angular“ et “keycloak-js”.

cd angular-ouidou && npm install keycloak-angular keycloak-js

Remarque : les versions des librairies utilisées lors de la rédaction de cet article sont respectivement 19.0.2 et 26.1.0.

Variables d’environnements

Avant de poursuivre, on génère les fichiers d’environnement pour y stocker les valeurs liées à Keycloak.

$ npx ng generate environments
CREATE src/environments/environment.ts (31 bytes)
CREATE src/environments/environment.development.ts (31 bytes)

Dans le fichier “environment.development.ts”, on saisit nos variables (l’URI de Keycloak, l’adresse de redirection, l’adresse de redirection du logout, le realm et le clientId).

export const environment = {
  production: false,
  title: 'Ouidou Corp',
  keycloak: {
    uri: 'http://localhost:8080',
    redirectUri: 'http://localhost:4200/dashboard',
    redirectUriLogout: 'http://localhost:4200/logout',
    realm: 'ouidou',
    clientId: 'angular-ouidou',
  },
};

Dans le fichier “environment.ts”, on laisse les variables à vide.

export const environment = {
  production: true,
  title: '',
  keycloak: {
    uri: '',
    redirectUri: '',
    redirectUriLogout: '',
    realm: '',
    clientId: '',
  },
};

Dans le fichier “tsconfig.json”, dans l’option “CompilerOptions”, ajoutez un alias pour le dossier des environnements.

"paths": {
  "@environments/*": ["./src/environments/*"]
}

Puis démarrez le serveur de développement avec la commande npm start.

Instancier la librairie Keycloak-Angular

Commençons par générer le fichier de configuration pour Keycloak avec la commande ci-dessous.

$ npx ng g class init/keycloak.config --type=factory --skip-tests
CREATE src/app/init/keycloak.config.ts (22 bytes)

Afin d’instancier la configuration de Keycloak en mode “check-sso”.

import { environment } from '@environments/environment.development';
import { provideKeycloak } from 'keycloak-angular';

export const provideKeycloakAngular = () =>
  provideKeycloak({
    config: {
      url: environment.keycloak.uri,
      realm: environment.keycloak.realm,
      clientId: environment.keycloak.clientId,
    },
    initOptions: {
      onLoad: 'check-sso',
      silentCheckSsoRedirectUri: `${window.location.origin}/silent-check-sso.html`,
      redirectUri: environment.keycloak.redirectUri,
    },
  });

Puis créez le fichier “silent-check-sso.html” dans le dossier “src/assets”.

<html>
  <body>
    <script>
      parent.postMessage(location.href, location.origin);
    </script>
  </body>
</html>

Afin que ce dossier soit prit en compte par Angular, modifiez le fichier “angular.json”.

"assets": [
  "src/assets"
],

On en profite également pour appeler le framework CSS, Pico CSS.

"styles": [
  "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css",
  "src/styles.css"
],

Puis dans le fichier “app.config.ts”, importez le module “provideKeycloakAngular” comme provider.

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideKeycloakAngular } from './keycloak.config';

export const appConfig: ApplicationConfig = {
  providers: [
    provideKeycloakAngular(),
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
  ],
};

Composants

Hormis la mire de connexion gérée par Keyloak, on va avoir besoin de composants tels que les pages d’accueil (“home”), du dashboard et de déconnexion (“logout”) ainsi que le composant de navigation.

Home

On commence donc par générer le composant de la page d’accueil avec la commande dédiée.

$ npx ng generate component home --skip-tests  --inline-template --style none
CREATE src/app/home/home.component.ts (187 bytes)
import { Component, inject, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { environment } from '@environments/environment';

@Component({
  selector: 'app-home',
  standalone: true,
  template: `<p>Vous êtes actuellement sur la page d'accueil.</p>`,
})
export class HomeComponent implements OnInit {
  private readonly titleService = inject(Title)

  ngOnInit() {
    this.titleService.setTitle(`Accueil | ${environment.title}`);
  }
}

Dashboard

Puis le composant de la page (bientôt protégée) du dashboard.

$ npx ng generate component dashboard --skip-tests --inline-template --style none
CREATE src/app/dashboard/dashboard.component.ts (202 bytes)
import { Component, inject, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { environment } from '@environments/environment';

@Component({
  selector: 'app-dasboard',
  standalone: true,
  template: `<p>Ceci est votre espace protégé.</p>`,
})
export class DashBoardComponent implements OnInit {
  private readonly titleService = inject(Title);

  ngOnInit() {
    this.titleService.setTitle(`Dashboard | ${environment.title}`);
  }
}

Logout

Puis la page de déconnexion qui informe l’utilisateur de sa déconnexion.

$ npx ng generate component logout --skip-tests --inline-template --style none  
CREATE src/app/logout/logout.component.ts (190 bytes)
import { Component } from '@angular/core';

@Component({
  selector: 'app-logout',
  template: `<p>Vous êtes désormais déconnecté(e)</p>`,
})
export class LogoutComponent {}

Navigation

On termine avec le composant de navigation qui va comporter de la logique car on a besoin de conditionner l’affichage en fonction de l’état de déconnexion (affichage par défaut) ou de connexion.

$ npx ng generate component navigation --skip-tests --style none
CREATE src/app/navigation/navigation.component.html (26 bytes)
CREATE src/app/navigation/navigation.component.ts (191 bytes)

Ci-dessous le contenu du fichier “navigation.component.ts”.

import { Component, inject, OnInit } from '@angular/core';
import { RouterModule } from '@angular/router';
import { environment } from '@environments/environment';
import Keycloak from 'keycloak-js';

@Component({
  selector: 'app-navigation',
  standalone: true,
  imports: [RouterModule],
  templateUrl: './navigation.component.html'
})
export class NavigationComponent implements OnInit {
  private readonly keycloak = inject(Keycloak);

  userName?: string;

  get isLoggedIn(): boolean  {
    return this.keycloak.authenticated ?? false;
  }

  ngOnInit(): void {
    if (this.isLoggedIn) {
      this.keycloak
        .loadUserProfile()
        .then((profile) => (this.userName = profile.username));
    }
  }

  redirectToLoginPage(): void {
    this.keycloak.login();
  }

  logout(): void {
    this.keycloak.logout({
      redirectUri: environment.keycloak.redirectUriLogout
    });
  }
}

Et son template (“navigation.component.html”), on affiche le menu de navigation conditionné.

<nav>
  <ul>
    <li><strong>Ouidou Corp</strong></li>
  </ul>
  <ul>
    <li>
      <a
        routerLink="/"
        routerLinkActive="active"
        ariaCurrentWhenActive="page"
        [routerLinkActiveOptions]="{ exact: true }"
        >Accueil</a
      >
    </li>
    @if(!isLoggedIn) {
    <li>
      <a href="javascript:void(0)" (click)="redirectToLoginPage()">Connexion</a>
    </li>
    } @else {
    <li>
      <a
        routerLink="/dashboard"
        routerLinkActive="active"
        ariaCurrentWhenActive="page"
        >Dashboard</a
      >
    </li>
    <li>
      <details class="dropdown">
        <summary>
          {{ userName }}
        </summary>
        <ul dir="rtl">
          <li>
            <a href="javascript:void(0)" (click)="logout()">Déconnexion</a>
          </li>
        </ul>
      </details>
    </li>
    }
  </ul>
</nav>

On importe ce composant dans le composant parent “app.component.ts”.

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { NavigationComponent } from "./navigation/navigation.component";

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, NavigationComponent],
  templateUrl: './app.component.html',
})
export class AppComponent {}

Et on met à jour le template “app.component.html”.

<div class="container">
  <app-navigation />
  <router-outlet />
</div>

Routes

Nos composants sont prêts, il ne nous reste plus qu’à mettre en place le routing de notre application.

Guard

Mais avant de ce faire, il faut créer le guard de Keycloak pour les futures pages accessibles uniquement pour les utilisateurs connectés.

$ npx ng generate guard keycloak --skip-tests
✔ Which type of guard would you like to create? CanActivate
CREATE src/app/keycloak.guard.ts (133 bytes)
import { inject, Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  CanActivate,
  RouterStateSnapshot,
  UrlTree,
} from '@angular/router';
import Keycloak from 'keycloak-js';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class KeycloakGuard implements CanActivate {
  private readonly keycloak = inject(Keycloak);

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    if (this.keycloak.authenticated) {
      return true;
    }

    this.keycloak.redirectUri;
    return false;
  }
}

Cela fait beaucoup de lignes de code, mais pour résumer, si l’utilisateur est connecté, il poursuit sa navigation. Sinon, il est redirigé sur la page de connexion Keycloak.

Déclaration des routes

Ainsi, on peut mettre à jour le fichier de routing avec la route d’accueil et celle du dashboard dans le fichier “app.routes.ts”.

import { Routes } from '@angular/router';
import { DashBoardComponent } from './dashboard/dashboard.component';
import { HomeComponent } from './home/home.component';
import { KeycloakGuard } from './keycloak.guard';
import { LogoutComponent } from './logout/logout.component';

export const routes: Routes = [
  { path: '', component: HomeComponent},
  { path: 'logout', component: LogoutComponent},
  {
    path: 'dashboard',
    component: DashBoardComponent,
    canActivate: [KeycloakGuard],
  },
];

Restriction par rôle

On a désormais une connexion fonctionnelle et une application en partie protégée. Pour aller plus loin, on veut restreindre l’accès à la future partie “managers” pour les utilisateurs disposant du rôle “view-managers”.

Configuration Keycloak

Dans l’administration de Keycloak, allez dans “Realm roles” puis cliquez sur le bouton “Create role”. Dans le champ “Role name”, saisissez “view-managers” et sauvegardez en cliquant sur le bouton “Save”.

Création d'un nouveau rôle

Pour attribuer ce rôle au groupe “managers”, cliquez sur “Groups” puis sur “managers”. Dans l’onglet “Role mapping”, cliquez sur le bouton “Assign role”. Dans la liste déroulante, sélectionnez “Filter by realm roles” afin de sélectionner le rôle “view-managers” et validez en cliquant sur le bouton “Assign”.

Assigner un rôle

Remarque : sur Keycloak, il est également possible d’ajouter un rôle à un utilisateur sans passer par un groupe.

Mise à jour de la navigation

Dans le composant “navigation.component.ts”, ajoutez la fonction booléenne ci-dessous pour savoir si l’utilisateur dispose du rôle “view-managers”.

get isManager(): boolean {
  return this.keycloak.hasRealmRole('view-managers') ?? false;
}

Afin de conditionner l’affichage dans la partie html (“navigation.component.html”).

@if(isManager) {
<li>
  <a
    routerLink="/managers"
    routerLinkActive="active"
    ariaCurrentWhenActive="page"
    >Managers</a>
</li>
}

Nouveau guard et nouvelle route

Générez le nouveau guard “managers.guard.ts” avec la commande ci-dessous.

$ npx ng generate guard managers --skip-tests
✔ Which type of guard would you like to create? CanActivate
CREATE src/app/managers.guard.ts (132 bytes)

On vérifie que l’utilisateur connecté possède le rôle “view-managers” sinon, on le redirige sur la page du dashboard.

import { inject, Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  CanActivate,
  Router,
  RouterStateSnapshot,
  UrlTree,
} from '@angular/router';
import Keycloak from 'keycloak-js';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class ManagersGuard implements CanActivate {
  private readonly keycloak = inject(Keycloak);
  private readonly router = inject(Router);

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    if (this.keycloak.hasRealmRole('view-managers')) {
      return true;
    }

    this.router.navigate(['/dashboard']);
    return false;
  }
}

Avant de créer la route, générez le composant “managers”.

$ npx ng generate component managers --skip-tests --inline-template --style none
CREATE src/app/managers/managers.component.ts (196 bytes)

Afin de modifier le fichier des routes (“app.routes.ts”).

{
  path: 'managers',
  component: ManagersComponent,
  canActivate: [KeycloakGuard, ManagersGuard],
},

Résultat

Avec un utilisateur disposant du rôle, on accède bien à la page “managers”.

Résultat avec le rôle manager

Avec un utilisateur ne disposant pas du rôle, on n’a pas accès à la page.

Résultat sans le rôle manager

Conclusion

La librairie “keycloak-angular” couplée à “keycloak-js” permet d’obtenir une connexion à Keycloak rapidement. La gestion des rôles permet de mettre en place un gestion plus fine de vos utilisateurs.

A noter que la mire d’authentification de Keycloak, est personnalisable afin de mieux coller au thème de votre application web.

Sources

  • Keycloak Angular : GitHub – mauriciovigolo/keycloak-angular: Easy Keycloak integration for Angular applications. ;
  • PicoCSS : https://picocss.com.

À lire aussi

Formations Atlassian certifiées Qualiopi avec Ouidou
18 septembre 2025

Formations Atlassian certifiées Qualiopi avec Ouidou

Lire la suite

Keycloak : Installation & configuration
5 septembre 2025

Keycloak : Installation & configuration

Lire la suite

Le Diamond Agile : Une approche évolutive pour une agilité maximale
6 août 2025

Le Diamond Agile : Une approche évolutive pour une agilité maximale

Lire la suite

Pacte mondial de l'ONU
29 juillet 2025

Ouidou adhère au Pacte mondial des Nations Unies

Lire la suite

Articles associés

Formations Atlassian certifiées Qualiopi avec Ouidou
18 septembre 2025

Formations Atlassian certifiées Qualiopi avec Ouidou


Lire la suite
Conférence A11Y miniature
30 juin 2025

Retour sur la Conférence A11Y Paris


Lire la suite
Fresque numérique miniature image
16 avril 2025

Fresque du Numérique


Lire la suite

À propos

  • Qui sommes-nous ?
  • Références
  • RSE
  • Ressources

Offres

  • Applications métier
  • Collaboration des équipes
  • Sécurisation et optimisation du système d’information
  • Transformation numérique

Expertises

  • Développement logiciel
  • DevSecOps
  • Intégration de logiciels et négoce de licences
  • Logiciel de CRM et de gestion
  • UX/UI design
  • Accessibilité Numérique
  • Démarches simplifiées
  • Formations Atlassian

Carrières

  • Pourquoi rejoindre Ouidou ?
  • Nous rejoindre
  • Rencontrer nos collaborateurs
  • Grandir chez Ouidou
logo ouidou

SIEGE SOCIAL
70-74 boulevard Garibaldi, 75015 Paris

Ouidou Nord
165 Avenue de Bretagne, 59000 Lille

Ouidou Rhône-Alpes
4 place Amédée Bonnet, 69002 Lyon

Ouidou Grand-Ouest
2 rue Crucy, 44000 Nantes

Ouidou Grand-Est
7 cour des Cigarières, 67000 Strasbourg

  • Linkedin Ouidou
  • GitHub Ouidou
  • Youtube Ouidou
© 2024 Ouidou | Tous droits réservés | Plan du site | Mentions légales | Déclaration d'accessibilité
    Nous contacter