I have a problem and I wanted to ask if someone might help me out there :)
In my application have a config.json file which contains some information depending on it's stages (e.g. dev, IN, Prod ...).
{
"queryUrl": "http://localhost:4200",
"commandUrl": "http://localhost:8282",
"ssoUrl": "https:someurlcode",
"ssoRealm": "someRealm",
"ssoClient": "dev"
}
This file I wanted to exchange after the application is build since its different for the different stages. (This works fine in the Jenkins Build)
Now I have written a Keycloak Service, where I create the token:
import { Injectable } from '@angular/core';
// @ts-ignore
import Keycloak from 'keycloak-js';
// @ts-ignore
import * as config from '../../../assets/config.json';
@Injectable({
providedIn: 'root'
})
export class KeycloakService {
private keycloakAuth: any;
private ssoUrl: string;
private ssoRealm: string;
private ssoClient: string;
constructor() {
this.ssoUrl = config.ssoUrl;
this.ssoRealm = config.ssoRealm;
this.ssoClient = config.ssoClient;
}
init(): Promise<any> {
console.log('init ' + this.ssoClient);
return new Promise((resolve, reject) => {
this.keycloakAuth = Keycloak({
url: this.ssoUrl,
realm: this.ssoRealm,
clientId: this.ssoClient
});
this.keycloakAuth.init({ onLoad: 'login-required' })
.then(() => {
console.log('keycloak success');
resolve();
})
.catch(() => {
console.log('keycloak error');
reject();
});
});
}
getToken(): string {
return this.keycloakAuth.token;
}
}
As you may see I load the Json via an import statement. If I exchange the file now, it still uses the old file --> guess that's obvious since its taken at build time.
Next here is my http interceptor:
import {Injectable} from '@angular/core';
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {KeycloakService} from './keycloak.service';
import {Observable, throwError} from 'rxjs';
import {catchError, retry} from 'rxjs/operators';
import {Router} from '@angular/router';
/**
* Passes on the KeyCloak token
*/
@Injectable()
export class KeycloakInterceptor implements HttpInterceptor {
constructor(private kcService: KeycloakService, private router: Router) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authToken = this.kcService.getToken() || '';
request = request.clone({
setHeaders: {
Authorization: 'Bearer ' + authToken
}
});
return next.handle(request).pipe(
retry(1),
catchError((error: HttpErrorResponse) => {
if (error.status !== undefined) {
this.router.navigate(['/error'], {queryParams: {errorCode: error.status}});
} else {
return throwError(error);
}
})
);
}
}
and also some insights from the app.module.ts
{
provide: APP_INITIALIZER,
useFactory: keycloakFactory,
deps: [KeycloakService],
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: KeycloakInterceptor,
multi: true
}
....
export function keycloakFactory(keycloakService: KeycloakService) {
return () => keycloakService.init();
}
I tried it a couple of times to load it in the init function etc. but always got an error like undefined etc...
Hope someone can help me...
Cheers Jack