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
- What is causing this error?
- 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.