Using Keycloak.js with Angular routes in Es6
- UI Router 1.0.3
- SystemJs
- Keycloak JS
- Angular 1.x
- Es6 transpiling
We stood up a keycloak server which serves as an identity provider for our organization. It’s a really powerful tool which allows for separation of clients into ‘realms’. This enables a true multi-tenant authorization environment. Not to mention it supports openId connect which enables use to federate users from practically anywhere. Needless to say, it hits all the marks.
Until using the client side javascript library.
While the provided library is very handy in abstracting all the necessary authorization methods it fails to play nicely with the SPA architecture so common on the web today. Searches seemed plagued with forum posts describing authorization loops and page reloading.
Myself finding an issue around the application bootstrapping before the auth redirect.
While this example does exactly what it’s designed to do, authenticate a user then boot strap the app, it provides zero flexibility around routes. What if i wanted only certain routes to be password protected, but not others? An error page is perfect example. A user should not be logged in to see errors.
If we call keycloak.init() inside of an angular service the app will be bootstrapped much too late and most of the application will have rendered.
I took a two edge approach. The first approach was loading the keycloak library and calling init using synchronous module loading in system.js (this can be achieved easy easier without module loading)
Create an auth.js file
This ensures that keycloak with be ‘available’ by the time that any other module is loaded.
Then just create a service that hooks into the UI router transition service
Because services are initiated before angular.run, the application will hook into the base route before its been built by UI router. The result is an application that blocks loading specific routes on the keycloak state. You also get all the benefits from they keycloak library such as iFrame session reloading. By blocking the UI from rendering before loading the route it also improves the experience of the user.
