Secure Angular4 app with Keycloak
Tech-Today

Secure Angular4 app with Keycloak


Demo template is available for sale for $50. You can send payment via skype at: [email protected]

Disclaimer: This is not a tutorial on how to setup an Angular^4 project, nor are we going to discuss how to setup a Keycloak server. Needless to say, you should already be familiar these tech before diving here.

I have a previous article you may want to check that discusses keycloak http://czetsuya-tech.blogspot.com/2017/04/how-to-signin-to-keycloak-using-google.html.

After creating your client in Keycloak, download the Keycloak OIDC JSON, under Installation tab as keycloak.json. We will use it later.

Angular project configuration (note I'm using version 4.4.3):

  1. Create your Angular project. I normally use Angular CLI. I assume you are already familiar with Angular initial project configuration.
  2. Put your keycloak.json inside app/assets folder. This will be consume by an angular service later.
  3. Install keycloak js
    >npm install keycloak-js --save
  4. Step 3 will generate a keycloak.js inside angular's node_modules folder. To use it we need to add an entry in .angular-cli.json. Look for scripts section and add "../node_modules/keycloak-js/dist/keycloak.js"
  5. Now that we have the keycloak library on our project. We need to create the service that will load it.

    import { Injectable } from '@angular/core';

    import { environment } from 'environments/environment';

    declare var Keycloak: any;

    @Injectable()
    export class KeycloakService {

    static auth: any = {};

    static init(): Promise<any> {
    let keycloakAuth: any = new Keycloak('assets/keycloak.json');
    KeycloakService.auth.loggedIn = false;

    return new Promise((resolve, reject) => {
    keycloakAuth.init({ onLoad: 'check-sso' })
    .success(() => {
    KeycloakService.auth.loggedIn = true;
    KeycloakService.auth.authz = keycloakAuth;
    KeycloakService.auth.logoutUrl = keycloakAuth.authServerUrl + "/realms/" + environment.keycloakRealm + "/protocol/openid-connect/logout?redirect_uri=http://localhost:4200/index.html";

    resolve();
    })
    .error(() => {
    reject();
    });
    });
    }

    // more methods here
    }

    This service loads keycloak.json from assets folder. It initialize keycloak using 'check-sso' parameter. Why? So that angular will not redirect to keycloak's login page every time we access a page. If login is successful we store the keycloak object in keyClockService's auth variable. Note that this variable is static, so we can access it in any of our angular's components, as long as we inject the service.
  6. Since we used check-sso parameter in keycloak, we need to manually secure the routes, which we don't want to be accessible by the general public. To do that, we need to create a guard that we can use in Routes. This is how we define the guard:

    import { Injectable } from '@angular/core';
    import { Router, CanActivate, CanLoad } from '@angular/router';

    import { Logger } from "angular2-logger/core";

    import { KeycloakService } from 'app/core/auth/keycloak.service';

    @Injectable()
    export class AuthGuardService implements CanActivate, CanLoad {

    constructor(public router: Router, private keycloakService: KeycloakService, private logger: Logger) {
    }

    canActivate(): boolean {
    return false;
    }

    canLoad(): boolean {
    if (KeycloakService.auth.loggedIn && KeycloakService.auth.authz.authenticated) {
    this.logger.info("user has been successfully authenticated");
    return true;

    } else {
    KeycloakService.login();
    return false;
    }
    }

    }
  7. Now we need to declare our AuthGuardService in our providers, so the system can access it. Open your app.module.ts and add it:
    AuthGuardService,
    {
    provide: HTTP_INTERCEPTORS,
    useClass: SecuredHttpInterceptor,
    multi: true
    },
  8. Then in our Routes definition (I assume you have app-routing.module.ts) we guard the Routes like this:
    { path: 'dashboard/vendor', canLoad: [AuthGuard], loadChildren: 'app/module/dashboard/vendor/vendor.module#VendorModule' }
  9. At this point all our prerequisites to secure the angular app had been already fulfilled. We just need to initialize keycloak somewhere when we access the app and there is no better place to do that but in main.ts.

    KeycloakService.init()
    .then(() => {
    const platform = platformBrowserDynamic();
    platform.bootstrapModule(AppModule);
    })
    .catch(() => window.location.reload());

    Perfect. Now keycloak will do nothing if there is no session cookie. Otherwise, it will login automatically and if the session is valid, redirects back to the app.
  10. Since most angular apps access a REST API, we normally would want to add a bearer token on any request whenever we have an authenticated user. We do that by implementing the newly introduced HttpInterceptor. And this is how we do it:

    import { Injectable } from '@angular/core';
    import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse } from '@angular/common/http';

    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/do';

    import { KeycloakService } from 'app/core/auth/keycloak.service';

    @Injectable()
    export class SecuredHttpInterceptor implements HttpInterceptor {

    intercept(
    request: HttpRequest<any>,
    next: HttpHandler

    ): Observable<HttpEvent<any>> {
    KeycloakService.getToken();
    let kcToken = KeycloakService.auth.authz.token;

    if (KeycloakService.auth.loggedIn && KeycloakService.auth.authz.authenticated) {
    request = request.clone({
    setHeaders: {
    Authorization: 'Bearer ' + kcToken
    }
    });
    }

    return next.handle(request);
    }
    }
  11. Finally we have everything to secure our angular app.
Demo template is available for sale for $50. You can send payment via skype at: [email protected]




- Secure Spring Boot Rest Project With Keycloak
1. OverviewIn this blog, we will cover the basics of securing a Spring project with Keycloak using keycloak-spring-boot-starter and keycloak-spring-security-adapter.2. LimitationKeycloak is already a well-documented topic that needs no further write up....

- Navigating In Guard In Angular5
There are some cases when we need to navigate in a Guard rather than in component. Why? Well, obviously you didn't have to define a component where you need to navigate. An example use case would be a route where you need to navigate given a certain...

- Multi-layout In Angular5
How to implement a multi-layout feature in Angular5. A common use case for this is when you have a different layout for your public and secured pages. For example, your secured page could have a menu on the left side. Or you have a page that doesn't...

- Keycloak Overlay Installation Failed
While playing with keycloak I have encountered several related problems: Keycloak 3.2.1 downloadable with samples is not working running.Installing keycloak 3.2.1 overlay on Wildfly 10.1.Final fails.Errors are:Caused by: org.jboss.modules.ModuleNotFoundException:...

- How To Signin To Keycloak Using Google
There are 3 set of steps that we must follow in order to come up with a web project that will allow us to login using google's identity provider. Set 1 - Create a google applicationCreate a google application at https://console.developers.google.com...



Tech-Today








.