DEV Community

Cover image for Quarkus + Angular with Keycloak — Pt1
Ricardo Mello
Ricardo Mello

Posted on

Quarkus + Angular with Keycloak — Pt1

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.

Image description


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 
Enter fullscreen mode Exit fullscreen mode

$ docker-compose up -d

If all goes well, we 'll have our container running:

Image description

Accessing Keycloak console

Type -> http://localhost:8188/admin and use admin/admin to sig in console.

Image description

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:

Image description

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:

Image description

Creating the users

Users are the users in the current realm. Let’s create ricas and pedro users and define a password for them:

Image description

Image description

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:

Image description

Setting role to user

Now, lets assign admin role just to ricas user:

Image description

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 
Enter fullscreen mode Exit fullscreen mode
  • Adding a nav-bar component:
$ ng g c navbar

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode
  • 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 { }
Enter fullscreen mode Exit fullscreen mode
  • 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>
Enter fullscreen mode Exit fullscreen mode

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

Image description

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

}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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)