Table of Contents
Overview
Today, I will show you how to configure Angular with Keycloak. I’m running Angular 14 and Keycloak 12.0.4 on Docker.
However, this should work with other setups. If not, please post a comment.
Let’s get started.
Configure Keycloak client
Let’s get started creating a Keycloak client.
![Create a new client in keycloak for the Angular app](https://datmt.com/wp-content/uploads/2022/09/create-keycloak-client-frontnend.png)
There are a few settings you need to pay attention to here:
- Client protocol: openid-connect
- Access type: public
- Valid Redirect URL: your app URL, you can add multiple URLs here by using the + button on the right. On the dev environment, put
http://localhost:4200
or whatever your URL is - Web Origin: for development purposes, put
*
. On prod, make sure to put your app URL only.
That’s it!
Configure Angular to work with keycloak
Now it’s time to configure settings in Angular.
Install dependencies
First, install keycloak-js
and keycloak-angular
. More details on keycloak-angular
can be found here on npm: https://www.npmjs.com/package/keycloak-angular.
npm install keycloak-angular keycloak-js
Create a file to check with Keycloak
Under the assets folder, create a file named silent-check-sso.html
with the following content:
<html> <body> <script> parent.postMessage(location.href, location.origin); </script> </body> </html>
Create Auth-guard
Now let’s create a route guard that checks with Keycloak.
First, generate a service:
npm run ng g s auth-guard
This will create a service. Here is the content you need to put in auth-guard.service.ts
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 override readonly router: Router, protected readonly keycloak: KeycloakService ) { super(router, keycloak); } override roles: any; public async isAccessAllowed( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ) { // Force the user to log in if currently unauthenticated. if (!this.authenticated) { await this.keycloak.login({ redirectUri: window.location.origin + state.url, }); } // Get the roles required from the route. const requiredRoles = route.data['roles']; // Allow the user to proceed if no additional roles are required to access the route. if (!(requiredRoles instanceof Array) || requiredRoles.length === 0) { return true; } // Allow the user to proceed if all the required roles are present. return requiredRoles.every((role) => this.roles.includes(role)); } }
In app.module.ts
, put the following code:
import { APP_INITIALIZER } from '@angular/core'; import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular'; //... more code function initializeKeycloak(keycloak: KeycloakService) { return () => keycloak.init({ config: { url: 'https://sso.openexl.com/auth/', realm: 'license-server-dev', clientId: 'frontend-angular' }, initOptions: { onLoad: 'check-sso', silentCheckSsoRedirectUri: window.location.origin + '/assets/silent-check-sso.html' } }); } @NgModule({ imports: [ // ... more imports.. KeycloakAngularModule ], declarations: [AppComponent], bootstrap: [AppComponent], providers: [ //put this { provide: APP_INITIALIZER, useFactory: initializeKeycloak, multi: true, deps: [KeycloakService] } //end keycloak ] })
Finally, let’s put the AuthGuard
in the router configuration:
{ path: 'feature-list', canActivate: [AuthGuard], // <-- put the guard here loadChildren: () => import('./features/feature-list/feature-list.module').then( (m) => m.FeatureListModule ) },
Now, you are done setting up. If you need a test user, check the next section.
Create a test user in Keycloak
Let’s head to Keycloak, select your realm and click on Users.
![Click on add user button](https://datmt.com/wp-content/uploads/2022/09/image-38-1024x192.png)
![Create new user in keycloak](https://datmt.com/wp-content/uploads/2022/09/image-37-1024x463.png)
Enter the details in the required boxes and make sure the settings at green arrows are configured like so.
After creating the user, make sure to set the password:
![Setting password for the user](https://datmt.com/wp-content/uploads/2022/09/image-39-1024x702.png)
On this screen, make sure Temporary is OFF!
Save the user and you are ready to test the Angular – Keycloak integration.
Test the app
Let’s go to the guarded route, if the user is not logged in, you will be redirected to Keycloak:
![](https://datmt.com/wp-content/uploads/2022/09/image-40-1024x618.png)
Enter your credentials and you will be redirected to the Angular app.
Troubleshooting
In my effort to do the Angular – Keycloak integration, I encountered a problem that made the app constantly redirect between angular and Keycloak. If you have the same issue, make sure initialNavigation
is NOT set to enableBlocking
:
RouterModule.forRoot(routes, { anchorScrolling: 'enabled', initialNavigation: 'enabledNonBlocking', //<-- use this or remove this settings completely }),
Angular & Keycloak starter project
If you want to quickly scaffolding an Angular with Keycloak already integrated, check this repo out:
https://github.com/datmt/angular-ngrx-material-starter-with-keycloak
I created this to support my future web development. Big thanks to the creator of this repo: https://github.com/tomastrajan/angular-ngrx-material-starter
Conclusion
In this post, I showed you how to integrate Angular with Keycloak. You can now focus on creating the next big web app instead of fixing user authentication problems.
![](https://datmt.com/wp-content/uploads/2023/02/1585613908477.jpeg)
I build softwares that solve problems. I also love writing/documenting things I learn/want to learn.