Keycloak – Integracja aplikacji frontendowej typu SPA dzięki Angular 11

Angular to jeden z najpopularniejszych frameworków do tworzenia aplikacji frontendowych typu single page, stworzony przez Google jako druga wersja Angular JS, jednak stał się on całkowicie nowym bytem. Dzięki TypeScript jest chętniej lubiany przez programistów Java.  Przejdźmy do Integracji Keycloaka z Angular!

Instrukcję lokalnej instalacji Keycloaka znajdziesz w tym poście.

Konfiguracja Keycloaka

Pierwszy krokiem jest skonfigurowanie klienta Keycloaka(aplikacji angularowej) w danym realmie. Na potrzeby wpisu skorzystamy z realmu domyślnego, czyli Master. Przejdźmy do zakładki clients w realmie master

Kolejno ustawmy Access Type na public gdyż aplikacja Angularowa nie może przechowywać client secrets (tak jak to było w przypadku backendu w Spring Boot) – cały kodzik jest widoczny w źródle przeglądarki więc na dzień dobry secrets skompromitowany.

Valid Redirect URIs czyli adres redirecta po poprawnym zalogowaniu do aplikacji Angularowej. Na potrzeby naszego wpisu wykorzystamy wildcard – czyli *.

Dodajmy odrazu użytkownika do testów w zakładce Users w realmie Master

I zmienmy hasło w sekcji Credentials. Keycloak gotowy!

Aplikacja Angularowa

Drugim krokiem jest instalacja pakiet menadżera(NPM) z tego linku. Następnie musimy zainstalować Angular CLI:

npm install -g @angular/cli 

W związku z powyższym wykonaniem komendy jesteśmy wstanie w kolejnych krokach używać komendy ng.

Następnie tworzymy szkielet aplikacji przy pomocy komendy:

ng new keycloak-app 

gdzie Keycloak-app to nazwa naszej aplikacji.

Kolejno przechodzimy do głównego katalogu aplikacji, która się wygenerowała i doinstalowujemy biblioteki do komunikacji z Keycloakiem przy pomocy poniższej komendy:

npm install keycloak-angular keycloak-js 

keycloak-js – to główna biblioteka do komunikacji z Keycloakiem.

keycloak-angular – dodatkowa biblioteka opakowywująca powyższa bibiloteke o mi.n AuthGuarda generycznego i Http Interceptora 

Czas na konfiguracje naszego projektu, otwieramy nasz projekt w dowolnym IDE (np Visual Studio Code czy IntelliJ)

Najpierw edytujemy plik app.module w celu konfiguracji biblioteki Keycloaka, podczas startu aplikacji


import { BrowserModule } from '@angular/platform-browser';
import {APP_INITIALIZER, NgModule} from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {KeycloakAngularModule, KeycloakService} from 'keycloak-angular';
import {HttpClientModule} from '@angular/common/http';
function initializeKeycloak(keycloak: KeycloakService): () => Promise<boolean> {
  return () =>
    keycloak.init({
      config: {
        url: 'http://localhost:8082/auth',
        realm: 'master',
        clientId: 'angular-app',
      }
    });
}
@NgModule({
  declarations: [AppComponent],
  imports: [AppRoutingModule, BrowserModule, KeycloakAngularModule],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initializeKeycloak,
      multi: true,
      deps: [KeycloakService],
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule { } 

initializeKeycloak – funkcja inicjująca service KeycloakService z danym url servera, realma i klienta, który został wcześniej utworzony. Można również te statyczne dane wynieść do pliku environment.ts.

APP_INITIALIZER – specjalny typ providera, który zostanie załadowany podczas startu aplikacji.

Kolejną rzeczą jest stworzenie tzw AuthGuarda, czyli wykorzystanie Guardów Angulara w celu zabezpieczenia przejscia do danych ścieżek aplikacji.W naszym przypadku, jeśli user nie będzie zalogowany to przekieruje go do strony logowania Keycloaka


import { Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  Router,
  RouterStateSnapshot,
} from '@angular/router';
import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';
@Injectable({
  providedIn: 'root',
})
export class AuthGuard extends KeycloakAuthGuard {
  constructor(
    protected readonly router: Router,
    protected readonly keycloak: KeycloakService
  ) {
    super(router, keycloak);
  }
  public async isAccessAllowed(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) {
    if (!this.authenticated) {
      await this.keycloak.login({
        redirectUri: window.location.origin + state.url,
      });
    }
    return true;
  }
}
 

Sprawdzamy czy użytkownik jest zalogowany, jesli nie to zostaje przekierowany do strony logowania keycloaka.

Na zakończenie skonfigurujmy app-routing.module.ts z powyższym guardem


import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {AuthGuard} from './auth-guard.guard';
import {AppComponent} from './app.component';
const routes: Routes = [{
  path: '',
  component: AppComponent,
  canActivate: [AuthGuard]
}];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { } 

W routes ustawiamy ścieżke ogólna dla AuthGuarda.

I tym sposobem połączylismy Keycloaka z aplikacją frontendową w Angularze. 

Jak zawsze przypominam o naszej grupie na Facebooku – można w niej zapytać dosłownie o wszystko a ktoś napewno udzieli odpowiedzi 🙂Jeśli masz jakiekolwiek pytania dotyczące tego wpisu – to jest idealne miejsce aby je zadać 🙂 

Przypominam również o zapisach na newsletter 🙂 Dzięki temu nie ominiesz żadnego wpisu. A bez wątpienia szykujemy się do bardzo ciekawej serii wpisów dotyczących Cloud Computingu.