Keycloak-Angular integration: Practical tutorial for connecting your app to a powerful IAM system

Paweł, Michał

Multiple authors

  • February 15, 2024

Contents

In today’s dynamic development environment, where security plays a key role, integrating an identity management system with the front-end layer – the part of the solution the users see and interact with – is becoming an integral part of IT projects. You need a robust IAM system with powerful capabilities to ensure the application’s security and comfort. 

One solution that has gained recognition in the programming world is Keycloak – an open-source identity and access management software. It not only provides a ready-made set of comprehensive tools to handle identity and access management but also allows for flexible configuration in accordance with the individual needs of the project.

In this article, we will show you how to integrate Keycloak with the front-end layer of an application based on Angular. We’ll analyze the steps necessary to successfully integrate the solution with your front end and discuss the benefits of this connection (including a look at the features available in the newest versions of Keycloak). We’ll also offer tips on configuration and practical implementation examples, focusing on guiding developers who want to effectively secure their applications while providing users with a smooth and user-friendly experience. 

What is Keycloak, and what are its benefits?

Keycloak is a powerful open-source solution that provides features related to authentication, authorization, federated identity, session management, and many other advanced concepts, making it an ideal choice for projects requiring a secure and integrated environment. That’s why, at Pretius, we recommend Keycloak to many of our clients. And no, we’re not being paid by the Keycloak team (which would be hard since it’s an open-source solution) – we just find it extremely useful.

There are many ways to quickly and easily set Keycloak up, which should satisfy the needs of various users. The platform supports numerous protocol standards such as OpenID Connect, OAuth 2.0 and SAML 2.0, making it compatible with various applications. This approach allows you to offer the SSO (Single Sign-On) functionality regardless of your solution’s architecture.

Keycloak is also containerized, making it a perfect solution for container-based environments such as Docker or Kubernetes. This is evidenced by many features of this platform, including:

  • Official Docker images – The Keycloak team provides and maintains official Docker images, ensuring they are up-to-date and secure.
  • Configuration via environment variables – It allows you to customize various aspects such as database, SSL connections, realm configuration, etc., without having to modify configuration files.
  • Integration with container orchestration tools – Keycloak integrates seamlessly with container orchestration platforms like Kubernetes, and you can use it in environments managed by the orchestrator. This allows you to dynamically manage Keycloak instances, easily scale based on workload, and take advantage of the benefits offered by container orchestration.
  • Extensive documentation – Keycloak also provides extensive documentation on configuration and deployment in containers, making it easier for users to understand the capabilities and benefits of integration with tools such as Podman, Docker, Kubernetes and OpenShift. 

Thanks to these functions, Keycloak is one of the most popular Identity and Access Management (IAM) solutions. To become more familiar with the topic of Keycloak and understand in detail the value of its use, I encourage you to read the Keycloak SSO – advantages of Single Sign-On and a ready-made access management system article (including the free Keycloak Cost Estimation Cheat Sheet) published on the Pretius blog. You can also check out our comprehensive Okta vs Keycloak comparison.

Project configuration

To demonstrate the advantages of using Keycloak, we will set up a server and integrate it with a simple front-end application written in Angular version 17. 

You’ll need to configure Keycloak. It’s a relatively simple process thanks to the documentation that guides the user step by step through the next steps, so we won’t show you how to do this in this article. Our server’s only purpose will be to demonstrate the topics discussed in the article, so we don’t need anything more. 

We will be working with a front-end application created in Angular 17, so let’s start by presenting the libraries that allow you to use Keycloak. We’ve employed two: 

  • keycloak-js – It’s an important element of the Keycloak ecosystem that enables you to secure web applications using the OpenID Connect protocol. This client-side JavaScript library is used to authorize and authenticate users in web applications. Thanks to its flexibility and ease of integration, keycloak-js has been used in many projects, as confirmed by data from the npm registry. Regular library updates also demonstrate active support from the community. Moreover, the library has built-in support for Cordova applications, which extends its use to mobile applications.
  • keycloak-angular – A wrapper library that makes using the library mentioned above easier in Angular applications. It extends the original features with additional functionality and adds new methods to make it easier to use within an Angular app. It also provides a basic implementation of AuthGuard, allowing you to customize your logic by using the authentication logic. It’s also possible to use the HttpClient Interceptor, which adds an authorization header to selected HTTP requests.

💀 Still working with the legacy AngularJS framework? Find out how to upgrade your apps from AngularJS to the new Angular

Project assumptions

For the purpose of this article, we need to have the ability to log out and be redirected to a dedicated log-out page. Also, our application needs to implement support for the basic functionalities provided by Keycloak. We distinguished the following scenarios that should be implemented:

  • Displaying pages available without logging in and blocking access to pages requiring authorization.
  • Implementation of the login process via Keycloak.
  • Downloading logged-in user data, including, e.g., the name received from the Keycloak server.
  • Access to protected sites only after successful login.
  • Automatic redirection of a non-logged-in user to the login page when accessing a protected page.
  • Possibility to log out and be redirected to a dedicated page confirming successful logout.

Initial app and Keycloak setup

Let’s start by downloading the Keycloak image for Docker from the official website. To run Keycloak in your local environment, simply use the following command:

docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:23.0.4 start-dev

After executing this command, you can go to the Keycloak panel at http://localhost:8080. To perform the required configuration, follow the guidelines on the official Keycloak website. After making all the changes, just leave the Keycloak process running in the console to enable communication with it.

The realm we created for this tutorial was called Pretius-Keycloak-FE-Integration, while the selected client id was keycloak-angular-integration-tutorial.

You must also create a new Angular project for your front-end application using the Angular 17 framework. To do this, open the console and go to the directory where you want to create the project. Then enter the ng new command and the name of our project as presented below:

ng new keycloak-fe-integration

You will then be asked for information about features to include in the initial design. Select options depending on your needs and preferences, or accept the default values.

In our project, we use these libraries in the following versions:

  • keycloak-js – ver. 22 
  • keycloak-angular – ver. 15

To download these libraries, enter the following command in the terminal in the project folder:

npm install keycloak-js@22 keycloak-angular@15 --save

After installing the necessary npm packages and other dependencies required by Angular, you will be greeted by the view of your workspace with a root directory called keycloak-fe-integration (if you used the same name we did). The next step will be to replace the existing file structure with the one indicated below:

A screenshot showing the file structure.

As you can see, all pages have been divided depending on their purpose in the pages folder. Before discussing the actual logic, let’s start by presenting the contents of the pages folder, which contains the components representing pages within the application. The main page of the application to which the user is redirected after the first launch is the main-page. So, let’s look at the logic behind it:

@Component({
  selector: 'app-main-page',
  standalone: true,
  imports: [NgIf],
  styleUrl: './main-page.component.scss',
  template: `<div class="content">
                <span class="title">Main page</span>
             </div>
             <a
                *ngIf="!isLoggedIn"
                role="button"
                class="button"
                (click)="redirectToLoginPage()"
                >
              Log In
              </a>`,
})
export class MainPageComponent {
  get isLoggedIn(): boolean {
    return this.authenticationService.isLoggedIn();
  }

  constructor(private readonly authenticationService: AuthenticationService) {}

  redirectToLoginPage(): void {
    this.authenticationService.redirectToLoginPage();
  }
}

The component only displays information about the user’s current location in the title and provides a button that allows logging in using Keycloak.

The next component to analyze is unprotected-route:

@Component({
  selector: 'app-unprotected-route',
  standalone: true,
  imports: [CommonModule],
  template: `
  <div class="content">
    <span class="title">Welcome {{ username }}!</span>
    <span class="status-text">This is an unprotected route</span>
  </div>
`
})
export class UnprotectedRouteComponent {
  get username(): string {
    return this.authenticationService.isLoggedIn()
      ? this.authenticationService.userName
      : 'friend';
  }
  constructor(readonly authenticationService: AuthenticationService) {}
}

As you can see, this component focuses only on displaying the user’s name when the user is logged in. Otherwise, you get the friend string.

If you then look at the protected-route component, you will also notice that it only focuses on displaying simple data:

@Component({
  selector: 'app-protected-route',
  standalone: true,
  template: `
  <div class="content">
    <span class="title">Welcome {{ authenticationService.userName }}!</span>
    <span class="status-text">This is a protected route</span>
  </div>
`
})
export class ProtectedRouteComponent {
  constructor(readonly authenticationService: AuthenticationService) {}
}

Also, in the case of the last two components, you only find simple code responsible for displaying plain HTML code. Below is the content of the not-found folder:

@Component({
  selector: 'app-not-found',
  standalone: true,
  template: `<h1>Page not found</h1>`
})
export class NotFoundComponent {}

And here is logout-screen displayed when the user logs out of the application:

@Component({
  selector: 'app-logout-screen',
  standalone: true,
  template: `
  <div class="content">
    <span class="title">You have been logged out!</span>
  </div>`
})
export class LogoutScreenComponent {}

As you can deduce from the code elements above, the individual pages do not affect the communication between Keycloak and the front end. When preparing the guide, we followed the principle of not placing logic in components. It can only be found in guards protecting access to appropriate pages and in the website containing the logic responsible for communication between the Angular application and Keycloak. Later in the article, we will discuss the most important elements and their role in the system. 

Keycloak configuration

After successfully installing the keycloak-angular library, you can configure the Keycloak module in a front-end app. First, define the environment variables used within the application. To do this, create a file, e.g. environment.ts, in the main project directory. Below are the variables used when creating our project:

export const environment = {
  production: false,
  keycloak: {
    authority: 'http://localhost:8080',
    redirectUri: 'http://localhost:4200',
    postLogoutRedirectUri: 'http://localhost:4200/logout',
    realm: 'Pretius-Keycloak-FE-Integration',
    clientId: 'keycloak-angular-integration-tutorial',
  },
  idleConfig: { idle: 10, timeout: 60, ping: 10 },
};

We’ll explain the exact purpose of these variables in the following sections. In short, they represent information regarding the configuration of the Keycloak server to which the Angular application will connect.

To ensure that Keycloak is initialized when the application starts, add the APP_INITIALIZER token and define a function to run in the application runtime, then add it to the AppModule, so that Keycloak initialization will take place with the appropriate configuration. In our application, we used a modular application solution. The content of this module is presented below:

export const initializeKeycloak = (keycloak: KeycloakService) => async () =>
  keycloak.init({
    config: {
      url: environment.keycloak.authority,
      realm: environment.keycloak.realm,
      clientId: environment.keycloak.clientId,
    },
    loadUserProfileAtStartUp: true,
    initOptions: {
      onLoad: 'check-sso',
      silentCheckSsoRedirectUri:
        window.location.origin + '/assets/silent-check-sso.html',
      checkLoginIframe: false,
      redirectUri: environment.keycloak.redirectUri,
    },
  });

@NgModule({
  bootstrap: [AppComponent],
  declarations: [AppComponent],
  imports: [
    RouterModule.forRoot(routes),
    BrowserModule,
    KeycloakAngularModule,
    CommonModule,
    HttpClientModule,
    NavigationBarComponent,
    FooterComponent,
  ],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initializeKeycloak,
      multi: true,
      deps: [KeycloakService],
    },
    provideUserIdleConfig({
      idle: environment.idleConfig.idle,
      ping: environment.idleConfig.ping,
      timeout: environment.idleConfig.timeout,
    }),
  ],
})
export class AppModule {}

This code allows you to configure Keycloak support within the application. The initializeKeycloak() function is key here, as it’s responsible for the correct initialization of this service. You must ensure that the data provided to it accurately reflects the configuration you have provided in Keycloak. To do this, set the following values in the config object:

  • url – The path to our Keycloak server (default localhost:8080).
  • realm – The name we gave to the realm we created in Keycloak.
  • clientId – The client name we assigned to our application in Keycloak, which will perform user authentication queries.

You also need to set loadUserProfileAtStartUp to force the application to download data about the currently logged-in user when it loads. Without this setting, after the user logs in, their data will not be available. This means that to use it, it will be necessary to download it manually.

The next object that you need to configure is initOptions. It’s a configuration object that allows you to customize the operation and initialization of Keycloak. The attributes that we set are:

  • onLoad – This attribute takes two values: login-required or check-sso. These options tell the adapter what strategy Keycloak should use for authentication. The login-required option forces authentication immediately – when the application starts, if the user is logged in to Keycloak, they will have access to the application, and if the user is not logged in, the login page will be displayed. The check-sso option, on the other hand, allows you to manage authentication status and appropriate redirections manually.
  • checkLoginIframe – This option specifies whether Keycloak should check login status using an iframe. Please use this option carefully because incorrect use may lead to problems such as constant page reloads.
  • redirectUri – It’s the URI (Uniform Resource Identifier) to which Keycloak redirects the user after a successful login.
  • silentCheckSsoRedirectUri – This option allows you to check the SSO status in the background without redirecting the browser to the Keycloak server and only then back to the application. Instead, this check is performed in a hidden iframe.

The value window.location.origin + /assets/silent-check-sso.html points to the location of the static HTML page file that is used for silent SSO checking. This file enables communication via iframe between the application and Keycloak. To do this, create this file in the specified location and place the following code in it:

<html>
  <body>
    <script>
      parent.postMessage(location.href, location.origin);
    </script>
  </body>
</html>

Available options may vary depending on the Keycloak version and application specifics. Check the Keycloak documentation for the most up-to-date information.

Configuration of the authentication service

After properly initializing and configuring the module to communicate with Keycloak, you can use the functions it provides. For this purpose, create a separate service  authorization.service.ts, which will provide you with the required methods to use Keycloak within the application. Since you only want to have one instance of this service within your application (singleton), use the standard approach when creating services via Angular CLI and leave the decorator @Injectable({ providedIn: ‘root’ }). Then, in the constructor, inject the service from the keycloak-angular library:

  constructor(private readonly keycloakService: KeycloakService) {}

With the service prepared, let’s move on to implementing a few useful methods. The first will be the method that allows users to log in to the application. So, create the redirectToLoginPage() method:

redirectToLoginPage(): Promise<void> {
    this.keycloakService.login();
  }

Now, move on to implementing the remaining methods. For the purposes of this project, you will require information about the username, login status and the ability to log out within the application. The implementation of individual methods is presented below:

get userName(): string {
    return this.keycloakService.getUsername();
  }

 isLoggedIn(): boolean {
    return this.keycloakService.isLoggedIn();
  }

  logout(): void {
    this.keycloakService.logout(environment.keycloak.postLogoutRedirectUri);
  }

As you can see, the API exposed by keycloak-angular allows you to implement all these requirements easily by calling the appropriate methods on the Keycloak website. It’s worth paying attention to the logout method, in which you can pass a parameter defining the path to which the user will be redirected after logging out of the application. As before, you also define this parameter using environment variables.

If you also want to implement automatic user logout after a specified period of inactivity, you can achieve this by calling the logout method, for example, using an external library that monitors user activity. We will demonstrate this effect using the angular-user-idle library. After completing the configuration according to the instructions included in the official documentation of the module, add the following code to the app.component.ts file:

ngOnInit(): void {
    if (this.authenticationService.isLoggedIn()) {
      this.userIdleService.startWatching();
      this.userIdleService
        .onTimerStart()
        .pipe(takeUntilDestroyed(this.destroyRef))
        .subscribe();

      this.userIdleService
        .onTimeout()
        .pipe(takeUntilDestroyed(this.destroyRef))
        .subscribe(() => {
          alert('Your session has timed out. Please log in again.');

          this.authenticationService.logout();
          this.userIdleService.resetTimer();
        });
    }
  }

The feature we have presented is designed to monitor user activity only after the user has logged in. This approach allows you to automatically log the user out of the application after a predefined period of time and then display appropriate information about it. However, it’s crucial to remember to reset the timer when calling this function. Otherwise, the alert will appear continuously, preventing the user from logging out.

Application routing 

After integrating with the Keycloak server, the next step is to create application routing and ensure appropriate access control to individual websites. To do this, let’s analyze the prepared app.routes.ts file, which lists individual subpages, and each of them is assigned appropriate access control using the canActivate guard:

export enum AppRoutes {
  Main = '',
  Protected = 'protected',
  Unprotected = 'unprotected',
  Logout = 'logout',
  NotFound = '404',
}

export const routes: Routes = [
  {
    path: AppRoutes.Main,
    pathMatch: 'full',
    component: MainPageComponent,
  },
  {
    path: AppRoutes.Protected,
    canActivate: [AuthGuard],
    component: ProtectedRouteComponent,
  },
  {
    path: AppRoutes.Unprotected,
    component: UnprotectedRouteComponent,
  },
  {
    path: AppRoutes.Logout,
    canActivate: [LogoutRouteGuard],
    component: LogoutScreenComponent,
  },
  {
    path: AppRoutes.NotFound,
    component: NotFoundComponent,
  },
  {
    path: '**',
    redirectTo: AppRoutes.NotFound,
  },
];

All subpages of our application are presented above. When analyzing the code, focus on the key parts for handling the logic related to authorization. To manage access to only selected pages, use guards on individual routes that you don’t want unlogged people to have access to. An example of such a page is the Protected page protected by AuthGuard. So, let’s examine how this guard works:

export const AuthGuard: CanActivateFn = (): boolean => {
  const authenticationService = inject(AuthenticationService);

  if (authenticationService.isLoggedIn()) {
    return true;
  }

  authenticationService.redirectToLoginPage();

  return false;
};

The above guard checks whether the user is logged in when trying to access a protected page. You do this using the isLoggedIn() method, which checks whether there is an active session for the current user and, depending on the result, redirects the user to the selected page or – if the active session is missing – to the login page. The second thing worth looking at is the page to which you are redirected after logging out. Here, you can also use a guard to manage access and limit the possibility of viewing it by a user who still has an active session in Keycloak. To do this, simply use the isLoggedIn() method provided by authorizationService.

export const LogoutRouteGuard: CanActivateFn = () => {
  const authenticationService = inject(AuthenticationService);
  const router = inject(Router);

  if (!authenticationService.isLoggedIn()) {
    return true;
  } else {
    return router.createUrlTree([AppRoutes.Main]);
  }
};

If the user has an active session, the guard will redirect them to the home page.

Final application analysis

In order to check whether the application works as it should, you should confirm the correctness of the scenarios described at the beginning of the article. Let’s start by displaying the application’s home page without logging in. First, let’s run our application with the following command:

ng serve

Now, open any browser and go to http://localhost:4200. The main page of the application should appear:

A screen showing the application.

As you can see, everything started properly. The paths available to us are displayed in the upper right corner. So let’s go to the next page by clicking the Unprotected button:

A screen showing the application.

Here too, the application allows you to redirect even without having an active session in Keycloak. So let’s check the last option available, i.e., press the Login button:

An image showing the log-in screen.

As a result of this action, the application correctly redirects us to the Keycloak login page. So, enter the user data and check whether you will be correctly authenticated.

A screen showing the application.

After logging in, you should land on the home page, where you should now see information that you have been correctly authenticated. Let’s take a look at what the Protected and Unprotected pages look like after logging in to the application:

A screen showing the application.

The application allows you to freely access the Protected page, where information with the name of the logged-in user is displayed. Next, let’s also check out the Unprotected page:

A screen showing the application.

The Unprotected page also now displays the name of the logged-in user, which confirms correct authorization. Now, when the user tries to go to the /logout path with an active session, according to the assumed logic, he should be taken back to the home page. To log out, click the Logout button in the upper right corner of the application:

A screen showing the application.

After pressing it, you land on a page informing you that you have been logged out, in accordance with the configuration we provided to Keycloak. As you can see, you no longer have an active session, as evidenced by the login status text under the page title. If, at this stage, you try to return to the protected page, i.e. Protected in our case, the application will automatically redirect you to the Keycloak login page.

What will happen if you don’t perform any actions for a long time and are authenticated after logging in? Try doing nothing for the time indicated in the module configuration from the angular-user-idle library. After this time has passed, you will be greeted by an alert informing you that you have been logged out of the session due to inactivity, and after confirming it, you will be redirected to the Dashboard without having an active session.

A screen showing the application.

Summary

In the context of an Angular-based application, the end-to-end authorization setup with Keycloak meets the access control requirements and provides a convenient and consistent experience for the end-user. Moreover, this IAM system allows you to address all potential concerns regarding the app’s data security standards. The Keycloak security team ensures you can sleep peacefully by constantly monitoring threats and releasing patches to protect against them.

The integration process is also very simple, thanks to the available libraries (keycloak-angular, keycloak-js). The API issued by keycloak-angular has been prepared to offer everything developers might require while creating an application. With this article, you should be capable of setting up a comprehensive tool which protects the application against any undesirable scenario. Also, a definite advantage of the keycloak-js and keycloak-angular libraries is undoubtedly the detailed documentation they offer. Thanks to it, understanding how the integration works and how to implement it is a relatively simple task.

If you’re thinking about implementing Keycloak at your company, consider dropping us a line. We’ve completed many enterprise-grade Keycloak projects for our clients, and we’ll be happy to share with you some case studies and estimate the possible costs of your Keycloak implementation. Such initial consultations are always free at Pretius, so just let us know about your needs – you can use the contact form below or write us at hello@pretius.com.

If you’re interested in Keycloak or Angular, you can also check out other articles on the Pretius blog:

  1. Keycloak SSO – advantages of Single Sign-On and a ready-made access management system
  2. Okta vs Keycloak: Comparison and easy Okta to Keycloak migration guide
  3. Migrating from Azure AD B2C to Keycloak – Possible scenarios and useful tips
  4. Oracle Access Management to Keycloak migration – When is it a good choice? How to do it right? 
  5. AngularJS upgrade: Why 2023 is the time for migrating and how to do it

Looking for a software development company?

Work with a team that already helped dozens of market leaders. Book a discovery call to see:

  • How our products work
  • How you can save time & costs
  • How we’re different from another solutions

footer-contact-steps

We keep your data safe: ISO certified

We operate in accordance with the ISO 27001 standard, ensuring the highest level of security for your data.
certified dekra 27001
© 2025 Pretius. All right reserved.