Integrating Keycloak with Angular? Let’s do it step by step

integracja_Keycloaka_z_Angular
Integrating Keycloak with Angular? Let’s do it step by step

Angular is one of the most popular frameworks for creating single-page frontend applications. Created by Google as the second version of Angular JS, has become a new entity. Thanks to TypeScript, Java developers are more willing to use it. Integrating Keycloak with Angular – this is how it looks step by step.

You can find instructions for installing Keycloak locally in this post.

Configuring Keycloak

The first step is to configure the Keycloak client (Angular application) in the given realm. For this post, we will use the default realm – Master. Go to the Clients tab in the Master realm.

Next, let’s set the Access Type to the public because an Angular application cannot store Client secrets (as it was in the backend case in Spring Boot) – all the code is visible in the browser source, so the secrets are compromised.

Valid Redirect URIs. It’s the redirect address after a valid login to the Angular application. For our post, we will use wildcard – that is *.

Let’s immediately add a user for testing in the Users tab in realm Master.

We also change the password in the Credentials section. Keycloak is ready!

Angular application

The second stage. We install the manager package (NPM) from this link. In the next step, we need to remember to install Angular CLI:

npm install -g @angular/cli 

After executing this command, we can use the ng command in the next steps.

Next, we create the skeleton of the application using the command:

ng new keycloak-app 

where Keycloak-app is the name of our application.

Next, we go to the root directory of the application that was generated and install the libraries to communicate with Keycloak using the following command:

npm install keycloak-angular keycloak-js 

keycloak-js – is the main library to communicate with Keycloak.

keycloak-angular – an additional library; that wraps the above library with generic AuthGuard and HTTP Interceptor.

It’s time to configure our Keycloak integration project with Angular. We open it in any IDE (e.g. Visual Studio Code or IntelliJ).

First, we edit the app.module file to configure the Keycloak library, at application startup.


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 – a function that initializes the KeycloakService with the given URL of the server, realm, and client that was created earlier. We can also take this static data into the environment.ts file.

APP_INITIALIZER – a special type of provider that will be loaded when the application starts.

The next thing we need to do is to create the so-called AuthGuard, which is the use of Angular’s Guards to secure the transition to the application paths in question. In our case, if the user is not logged in, he will be redirected to the Keycloak login page.


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;
  }
}
 

Now let’s check if the user is logged in. If not, he is redirected to the keycloak login page.

Finally, let’s configure app-routing.module.ts with the above guard


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 { } 

In routes, we set a generic path for AuthGuard.

In this way, we have connected Keycloak to the frontend application in Angular.