Skip to content

humbertodosreis/angular-keycloak-demo

Repository files navigation

Angular Keycloak Demo App

About

Tutorial demonstrating how to configure an application with authentication and authorization through Keycloak.

This demo we utilize a keycloak-angular lib, more details here.

Quickstart

  1. Clone the angular-keycloak-demo repository.
git clone https://github.com/humbertodosreis/angular-keycloak-demo
  1. Run project.
ng serve --open

Keycloak

  1. Create a user.

  1. Create and configure a client in Keycloak like image as below

keycloak-account-scope

Angular

  1. Then configure the environment.ts files to your Keycloak Instance

./src/environments/environment.ts

import { KeycloakConfig } from "keycloak-angular";

// Add here your keycloak setup infos
const keycloakConfig: KeycloakConfig = {
  url: "KEYCLOAK-INSTANCE-URL", // http://localhost:8080/auth
  realm: "REALM-NAME", // your realm: keycloak-sandbox
  clientId: "CLIENT-ID-NAME", // angular-keycloak-tutorial
};

export const environment = {
  production: false,
  // ...
  keycloakConfig,
};
  1. Initialize KeycloakService

In this tutorial, we go to set up the initialization the KeycloakService using the ngDoBootstrap. , another way is using the APP_INITIALIZER, see plugin's docs for more details .

  1. Setup app.module.ts

./src/app.module.ts

import { NgModule, DoBootstrap, ApplicationRef } from "@angular/core";
import { KeycloakAngularModule, KeycloakService } from "keycloak-angular";

const keycloakService = new KeycloakService();

@NgModule({
  imports: [KeycloakAngularModule],
  providers: [
    {
      provide: KeycloakService,
      useValue: keycloakService,
    },
  ],
  entryComponents: [AppComponent],
})
export class AppModule implements DoBootstrap {
  async ngDoBootstrap(app) {
    const { keycloakConfig } = environment;

    try {
      await keycloakService.init({ config: keycloakConfig });
      app.bootstrap(AppComponent);
    } catch (error) {
      console.error("Keycloak init failed", error);
    }
  }
}
  1. Create a app.guard

./app/app-auth.guard.ts

import { Injectable } from "@angular/core";
import {
  CanActivate,
  Router,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
} from "@angular/router";
import { KeycloakService, KeycloakAuthGuard } from "keycloak-angular";

@Injectable()
export class AppAuthGuard extends KeycloakAuthGuard implements CanActivate {
  constructor(
    protected router: Router,
    protected keycloakAngular: KeycloakService
  ) {
    super(router, keycloakAngular);
  }

  isAccessAllowed(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Promise<boolean> {
    return new Promise(async (resolve, reject) => {
      if (!this.authenticated) {
        this.keycloakAngular.login();
        return;
      }
      console.log(
        "role restriction given at app-routing.module for this route",
        route.data.roles
      );
      console.log("User roles coming after login from keycloak :", this.roles);

      const requiredRoles = route.data.roles;
      if (!requiredRoles || requiredRoles.length === 0) {
        return resolve(true);
      } else {
        if (!this.roles || this.roles.length === 0) {
          resolve(false);
        }
        let granted: boolean = false;
        for (const requiredRole of requiredRoles) {
          if (this.roles.indexOf(requiredRole) > -1) {
            granted = true;
            break;
          }
        }
        resolve(granted);
      }
    });
  }
}

Authorization

Steps below describe how to setup authorization.

Keycloak

  1. Create Roles

  1. Assign Role to User

Angular

In src/app/app-routing.module.ts, associate role to route

const routes: Routes = [
  {
    path: "",
    component: HomeComponent,
  },
  {
    path: "patients",
    component: PatientsListComponent,
    canActivate: [AppAuthGuard],
    data: {
      roles: ["Secretary", "Doctor", "Role Test"],
    },
  },
];

Testing

Further Reading

About

Tutorial how to setup angular app and Keycloak

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published