Keycloak Angular 2 - Check authenticated status Keycloak object

xDs picture xDs · Dec 24, 2016 · Viewed 8.8k times · Source

I'm implementing the Keycloak authentication service in my Angular 2 project. I use a service for logging in, logging out etc.

Authenticating a user and logging out seems to work. I'm now trying to protect some routes. I now have a working AuthGuard. To check if the user is logged in (in the AuthGuard), I have a isAuthenticated() method in the service. This is the service:

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

declare let Keycloak: any;

@Injectable()
export class KeycloakService {
  private keycloak = new Keycloak('app/keycloak/keycloak.json');

  constructor() {
    this.keycloak.init({onload: 'check-sso'});
    console.log(this.keycloak);
  }

  public login() {
    this.keycloak.login();
  }

  public logout() {
    this.keycloak.logout();
  }

  public isAuthenticated() {
    return this.keycloak.authenticated;
  }
}

Flow: User logs in, user tries to reach protected route, AuthGuard checks if user is logged in via isAuthenticated().

Note: I don't want to authenticate the user for the complete Angular app. Only for some routes.

Problem

After the user logs in, the user is redirected to the Angular app. After this, the isAuthenticated() method returns still false. Here is why:

I logged the Keycloak object to the console. I found something I didn't understand.

Keycloak object after login redirect

Keycloak object after login redirect


Same Keycloak object after login redirect (but expanded)

Same Keycloak object after login redirect (but expanded)

First the authenticated property is false. After expanding the authenticated property is true.

Question

Is the way I try to maintain my Keycloak object the correct way?

Consulted sources

And others

Answer

hakamairi picture hakamairi · Jan 12, 2017

Basing on the community provided Angular2 example in keycloak's github you can spot some differences in interacting with keycloak js adapter. Mainly the actual check on the authenticated (and possibly userName) is done on the promise returned from init.

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

      return new Promise((resolve, reject) => {
        keycloakAuth.init({ onLoad: 'login-required' })
          .success(() => {
            KeycloakService.auth.loggedIn = true;
            KeycloakService.auth.authz = keycloakAuth;
            KeycloakService.auth.logoutUrl = keycloakAuth.authServerUrl + "/realms/demo/protocol/openid-connect/logout?redirect_uri=/angular2-product/index.html";
            resolve();
          })
          .error(() => {
            reject();
          });
      });
}

Also the official keycloak js adapter's documentation uses promise for the authenticated check

<head>
    <script src="keycloak.js"></script>
    <script>
        var keycloak = Keycloak();
        keycloak.init().success(function(authenticated) {
            alert(authenticated ? 'authenticated' : 'not authenticated');
        }).error(function() {
            alert('failed to initialize');
        });
    </script>
</head>