The purpose of this article is to explore the authentication mechanism of Keycloak. We are going to create a daily-quotes application using Angular + Quarkus to achieve this goal. This article is divided into 3 parts.
1.The first part, we 'll start the Keycloak in a container and create the frontend project using Angular.
2.The second part, we 'll create our backend in Quarkus.
3.The third and final part, we 'll adjust the frontend to communicate with the backend.
Daily Quotes Application
The goal of this application is to create and list motivating messages. Only logged users will be able to see the messages. However, only users with admin role will be able to generate new messages.
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 using docker-compose up. Here we have a docker-compose.yml example:
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
$ docker-compose up -d
If all goes well, we 'll have our container running:
Accessing Keycloak console
Type -> http://localhost:8188/admin and use admin/admin to sig in 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:
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:
Creating the users
Users are the users in the current realm. Let’s create ricas and pedro users and define a password for them:
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:
Setting role to user
Now, lets assign admin role just to ricas user:
Very good 😻, our Keycloak is set. We’ve created our realm, client, users, and an admin role.
Angular application
In this topic, we 'll create our Angular application and add some components to it. Later, we 'll change our components to adapt them with the Keycloak security mechanism.
- 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
Very good 😻, we have our structure created and now we have to initialize Keycloak on 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’ll create a initializeKeycloak function and provides some informations. Inside keycloak.init we define keycloak url, realm and clientId that we’v created before. Our file must be like this:
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 { }
- Now, inside assets folder, let's create a silent-check-sso.html file:
<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/
Admin access
As our application was designed, we want to allow access to admin menu item only to users with admin role. For this, we will do the following steps:
- The navbar.component.ts should be like this:
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 these above step, we get all roles of the current user and check if he has the admin role
- The navbar.component.html must be like this:
<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
On this article, we saw how to configure and apply authentication with Keycloak in an Angular application. On the next article, we 'll implement the backend with Quarkus.
Feel comfortable to suggest, comment and contribute with this project. You can find the complete source here on my GitHub.
Thanks ❤️
Top comments (0)