Quarkus + Angular with Keycloak — Pt1

Ricardo Mello
ITNEXT
Published in
6 min readMar 15, 2023

--

Discover more on YouTube: If you’re looking for video content on technology, programming, and other topics, check out my YouTube channel! Subscribe to stay updated and learn more about these subjects.

This article aims to delve into the authentication mechanism of Keycloak, and the creation of a daily-quotes application using Angular + Quarkus. The article is divided into three parts.

  1. In the first part, we will begin by starting Keycloak in a container and creating the frontend project using Angular.
  2. The second part will involve the creation of our backend in Quarkus.
  3. Finally, in the third and final part, we will make adjustments to the frontend to enable communication with the backend.

Daily Quotes Application

The primary goal of this application is to create and display motivational messages. Access to these messages will be restricted to logged-in users only. Additionally, only users with admin privileges will be able to create new messages.

Application sample.

What is Keycloak?

Keycloak is an open source identity and access management solution. It uses open protocol standards like OpenID Connect or SAML 2.0 to secure your applications. The WebApps redirect the user to the Keycloak authentication server where the authentication control is carried out, isolating this entire process in a single point.

Setting up a Keycloak server

Let’s launch our local Keycloak instance by running the docker-compose up command.

  • Here's an example docker-compose.yml file that you can use:
services:  
daily-quote-keycloak:
image: quay.io/keycloak/keycloak
ports:
- "8188:8080"
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
command:
- start-dev
- --import-realm
volumes:
- /home/keycloak/realm.json:/opt/keycloak/data/import/realm.json
  • Now, just run on the terminal:
$ docker-compose up -d

Great! If everything goes as planned, our container should now be up and running:

container running inside docker

Accessing Keycloak console

Type http://localhost:8188/admin in your web browser and use admin/admin as the username and password to sign in to the Keycloak console:

Keycloak login console

Creating Realm

A realm manages a set of users, credentials, roles, and groups.

  • Let’s define the name of our realm with the name of our application daily-quotes:
Create realm

Creating Client

Clients are applications and services that can request authentication of a user. Let’s define the name of our client as frontend.

  • The configuration must be like this:
Client settings

Creating the users

Users are the users in the current realm.

  • Let’s create ricas and pedro users and define a password for them:
Create user
Setting password for user

Creating realm roles

Realm roles are the roles that you define for use in the current realm.

  • At this point, we’ll create an admin role:
Create a role

Setting role to user

  • Now, lets assign admin role just to ricas user:
Assign roles to user

Excellent 😻 !! With Keycloak now set up, we have created a realm, client, users, and an admin role, and assigned the admin role to the ricas user.

Angular application

In this section, we will begin by creating an Angular application and adding necessary components to it. Later on, we will modify these components to integrate them with the Keycloak security mechanism.

Hands On

  • Lets create our project and components:
$ mkdir daily-quotes
$ cd daily-quotes
$ ng new frontend
$ ng add @angular/material
  • Adding a nav-bar component:
$ ng g c navbar

Excellent!😻 With our application structure in place, the next step is to initialize Keycloak within our application.

Configuring Keycloak

  • First of all, let's add a Keycloak dependency:
$ sudo npm install keycloak-angular keycloak-js

Now, inside app.module.ts, we will create an initializeKeycloak function and provide the necessary information. Within the keycloak.init function, we will define the Keycloak URL, realm, and client ID that we created previously.

  • Here is an example of what our file might look like:
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { QuotesComponent } from './quotes/quotes.component';
import { NavbarComponent } from './navbar/navbar.component';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule} from '@angular/material/menu';
import { MatIconModule } from '@angular/material/icon';

export function initializeKeycloak(keycloak: KeycloakService) {
return () =>
keycloak.init({
config: {
url: 'http://localhost:8188',
realm: 'daily-quotes',
clientId: 'frontend'
},
initOptions: {
onLoad: 'login-required',
silentCheckSsoRedirectUri:
window.location.origin + '/assets/silent-check-sso.html'
}
});
}

@NgModule({
declarations: [
AppComponent,
NavbarComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatToolbarModule,
MatButtonModule,
MatMenuModule,
MatIconModule,
KeycloakAngularModule,
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializeKeycloak,
multi: true,
deps: [KeycloakService],
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
  • Next, let’s create a new file called silent-check-sso.html inside the assets folder:
<html>
<body>
<script>
parent.postMessage(location.href, location.origin);
</script>
</body>
</html>

All ready! Our configuration is done! Let’s start our serve and see the results on http://localhost:4200/

http://localhost:4200

Admin access

As per our application design, we aim to restrict access to the admin menu item to users with admin privileges. To accomplish this, we will follow these steps:

  • Modify the navbar.component.ts file as follows:
import { Component, OnInit } from '@angular/core';
import { KeycloakService } from 'keycloak-angular';

@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit {
constructor(private readonly keycloak: KeycloakService) { }

public hasAdminRole: boolean = false;

ngOnInit(): void {
this.hasAdminRole = this.keycloak.getUserRoles().includes('admin');
}

public async logout() {
this.keycloak.logout();
}

}

In the previous steps, we obtained all the roles for the current user and checked if they have the admin role.

  • Modify the navbar.component.html file as follows:
<mat-toolbar color="primary">
Daily Quotes
<a mat-button href="/">Home</a>
<a mat-button href="/quotes">Quotes</a>

<div *ngIf="hasAdminRole">
<button mat-button [matMenuTriggerFor]="afterMenu">Admin</button>
<mat-menu #afterMenu="matMenu" xPosition="after">
<button mat-menu-item onclick="new()">Add new Quote</button>
</mat-menu>
</div>
<a mat-button (click)="logout()">Logout</a>
</mat-toolbar>

Conclusion

In this article, we have learned how to configure and apply authentication with Keycloak in an Angular application. In the next article, we will implement the backend with Quarkus.

Please feel free to suggest, comment, and contribute to this project. You can find the complete source code on my GitHub page.

Thank you ❤️

--

--

Senior Software Engineer, member of the MongoDB Community Creator passionate about travel and football. Oracle Certified Associate, Java SE 8 Programmer