Home > OS >  What makes Keycloak's AuthGuard class throw this error in an Angular 14 app?
What makes Keycloak's AuthGuard class throw this error in an Angular 14 app?

Time:01-27

I am working on an app in Angular 14 that requires authentication/authorization, reason for witch I use Keycloak Angular. I need to guard certain routes.

As per the instructions, I have first installed Keycloak Angular with:

npm install keycloak-angular keycloak-js

In shared/auth-guard.service.ts I have:

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);
  }

  public async isAccessAllowed(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) {
    if (!this.authenticated) {
      await this.keycloak.login({
        redirectUri: window.location.origin   state.url
      });
    }
  }
}

I have imported the above service in my application's routing module:

import { AuthGuard } from './shared/auth-guard.service';

const routes: Routes = [
  { path: '', component:  HomeComponent },
  { path: 'login', component:  LoginComponent },
  { path: 'profile', component:  ProfileComponent }
];

The problem

Importing the AuthGuard service throws the error:

Property 'isAccessAllowed' in type 'AuthGuard' is not assignable to the same property in base type 'KeycloakAuthGuard'.

The error refers to the isAccessAllowed() method in the auth-guard.service.ts file.

Questions

  1. What is causing this error?
  2. What is the easiest and most reliable way to fix it?

CodePudding user response:

You method implementation does not match the type definition of the base class because you do not return anything if the user is authenticated.

The method definition from keycloak-angular for isAccessAllowed():

abstract isAccessAllowed(route: ActivatedRoute, state: RouterStateSnapshot): Promise<boolean | UrlTree>;

The method has a return type of Promise<boolean | UrlTree>.

You need to return a value if the user is already authenticated. They can access the route and the guard should indicate that. Try making this change:

public async isAccessAllowed(
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) {
  if (!this.authenticated) {
    await this.keycloak.login({
      redirectUri: window.location.origin   state.url
    });
  }
  return true;
}

EDIT: You add it to your routes like so:

import { AuthGuard } from './shared/auth-guard.service';

const routes: Routes = [
  { path: '', component:  HomeComponent },
  { path: 'login', component:  LoginComponent },
  { path: 'profile', component:  ProfileComponent, canActivate: [AuthGuard] }
];

See the Angular docs on route guards.

  • Related