x)- [ ] bug report -> please search for issues before submitting
- [x ] feature request
Can we extend KeycloakAuthGuard to support CanLoad and CanActivateChild.
This will be very useful for lazy routed modules.
@NehalDamania, I will take a look at your feature request. I'm pretty busy last days, so as soon as I have some time available I will send you a feedback. Thanks!
Ditto, this is actually the other most important use case of angular routing.
My current workaround/solution, for whoever needs it. @mauriciovigolo if you would like a MR, let me know.
Assuming that a route uses lazy load:
1) point to our auth guard in the respective angular route definition
canLoad: [AuthGuard],
loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule)
2) implement CanLoad in the AuthGuard
@Injectable()
export class AuthGuard extends KeycloakAuthGuard implements CanLoad {
constructor(protected router: Router, protected keycloakAngular: KeycloakService) {
super(router, keycloakAngular);
}
canLoad(route: Route, segments: UrlSegment[]): boolean | Observable<boolean> | Promise<boolean> {
return new Promise(async (resolve, reject) => {
try {
this.authenticated = await this.keycloakAngular.isLoggedIn();
this.roles = await this.keycloakAngular.getUserRoles(true);
const result = await this.checkAccessAllowed(route.data);
resolve(result);
} catch (error) {
reject('An error happened during access validation. Details:' + error);
}
});
}
isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
return this.checkAccessAllowed(route.data);
}
checkAccessAllowed(data: Data): Promise<boolean> {
return new Promise(async (resolve, reject) => {
if (!this.authenticated) {
this.keycloakAngular.login().catch(e => console.error(e));
return reject(false);
}
const requiredRoles = data as string[];
if (!requiredRoles || requiredRoles.length === 0) {
return resolve(true);
} else {
if (!this.roles || this.roles.length === 0) {
resolve(false);
}
let granted = false;
for (const requiredRole of requiredRoles) {
if (this.roles.indexOf(requiredRole) > -1) {
granted = true;
break;
}
}
resolve(granted);
}
});
}
}
Most helpful comment
My current workaround/solution, for whoever needs it. @mauriciovigolo if you would like a MR, let me know.
Assuming that a route uses lazy load:
1) point to our auth guard in the respective angular route definition
2) implement CanLoad in the AuthGuard