add dependency :
npm install --save keycloak-angular@latest
edit app module add provider and replace bootstrap by entryComponents and add keycloakService.init
import { KeycloakService, KeycloakAngularModule } from 'keycloak-angular';
@NgModule({
imports: [KeycloakAngularModule],
providers: [
{
provide: KeycloakService,
useValue: keycloakService
}
],
entryComponents: [AppComponent]
})
export class AppModule {
ngDoBootstrap(app) {
keycloakService.init({config,environment.settings.keycloakJsonUrl,
enableBearerInterceptor: true, // Activate HttpInterceptor for add Bearer all request
bearerExcludedUrls: ['/assets', '/api/nonesecure'] ) // Exclude bearer for this request
.then(() => {
console.log('[ngDoBootstrap] bootstrap app');
app.bootstrap(AppComponent);
})
.catch(error => console.error('[ngDoBootstrap] init Keycloak failed', error));
}
}
Add AuhtGuard
ng g auth auth/auth
Edit auth-guard.ts and replace by this
import { Injectable, Output } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';
import { Subject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthGuard extends KeycloakAuthGuard implements CanActivate {
private _roleError: Subject<any> = new Subject();//To broadcast role
constructor(protected router: Router, protected keycloakAngular: KeycloakService) {
super(router, keycloakAngular);
}
public onRoleError(): Observable<any> {
return this._roleError.asObservable();
}
isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
return new Promise((resolve, reject) => {
if (!this.authenticated) {
this.keycloakAngular.login()
.catch(e => console.error(e));
return reject(false); // throw Error: Uncaught (in promise): An error happened during access validation. Details:false in console
}
const requiredRoles: string[] = route.data.roles;
if (!requiredRoles || requiredRoles.length === 0) {
return resolve(true);
} else {
if (!this.roles || this.roles.length === 0) {
this._roleError.next(null);
resolve(false);
}
if (requiredRoles.every(role => this.roles.indexOf(role) > -1)) {
resolve(true);
} else {
this._roleError.next(null);
resolve(false);
}
}
});
}
}
Edit routing module and protect your routes :
const routes: Routes = [
{
path: "",
redirectTo: "/home",
pathMatch: 'full'
},
{
path: "home",
component: HomeComponent
},
{
path: "secure",
component: SecureComponent,
canActivate: [AuthGuard]
},
{
path: "admin",
component: AdminComponent,
data: {
roles: ["ADMIN_APP"]
},
canActivate: [AuthGuard],
}
];
Subscribe component toevent for an refused access by role
this.authGuard.onRoleError().subscribe(() => {
this.showMessage();
})
get userProfile
this.keycloakService.loadUserProfile().then((profile) => {
console.log(profile);
})
subscribe to keycloakEvent
this.keycloakService.keycloakEvents$.subscribe(e => {
console.log(e);
})