Looks great! I would happily join forces with Emillien. Most of the groundwork
is there.
On 10 February 2017 at 23:43:38, Stan Silvert
(ssilvert@redhat.com(mailto:ssilvert@redhat.com)) wrote:
Emillien Bondu has also done a lot of work in this area. Have you see
this?
https://github.com/ebondu/angular2-keycloak
On 2/10/2017 9:45 AM, Tair Sabirgaliev wrote:
> Here is the PR
https://github.com/keycloak/keycloak/pull/3855
>
> I don’t know how to properly QA demos, please give me some
> guidance on that, and I would be happy to maintain Angular 2
> integration code later on.
>
> Here are some ideas I can work on:
>
> - upgrade to latest Angular
> - refactor Keycloak service to a non-static singleton (a proper service)
> - properly handle the session expiration in Keycloak service
> - use ng-cli
> - integration test the sample app
> - use Angular routes and guards to secure HTML5 navigation
> - experiment with alternative authentication flows
>
> and more!
>
> Why not have a real kitchensink-style Angular application a part of samples :)
>
> Thank you!
>
>
> On 10 February 2017 at 19:29:39, Stan Silvert
> (ssilvert@redhat.com(mailto:ssilvert@redhat.com)) wrote:
>
>> Thanks Tair. I'll be looking into this very soon. Probably next week.
>>
>> On 2/9/2017 6:19 PM, Tair Sabirgaliev wrote:
>>> 1. The KeycloakHttp implementation overrides all the http methods, but
>>> in the
>>> Http class they all forward to 'request(...)' method, so overriding
>>> `request(...)` should be enough.
>>>
>>> 2. It is not obvious why the implementation uses Observable.merge.
>>> AFAICT the idea is to:
>>>
>>> (1) obtain the token (and update it BTW),
>>> (2) put it in header,
>>> (3) forward to superclass implementation.
>>>
>>> So we found that the whole KeycloakHttp implementation could be
>>> reduced to the following:
>>>
>>> @Injectable()
>>> export class KeycloakHttp extends Http {
>>> constructor(_backend: ConnectionBackend, _defaultOptions:
>>> RequestOptions, _keycloakService: KeycloakService) {
>>> super(_backend, _defaultOptions);
>>> }
>>>
>>> request(url: string | Request, options?: RequestOptionsArgs):
>>> Observable {
>>> const tokenPromise: Promise =
>>> this._keycloakService.getToken();
>>> const tokenObservable: Observable =
>>> Observable.fromPromise(tokenPromise);
>>>
>>> if (typeof url === 'string') {
>>> return tokenObservable.map(token => {
>>> const authOptions = new RequestOptions({
>>> headers: new Headers({'Authorization': 'Bearer ' +
>>> token})
>>> });
>>> return new
>>> RequestOptions().merge(options).merge(authOptions);
>>> }).concatMap(opts => super.request(url, opts));
>>> } else if (url instanceof Request) {
>>> return tokenObservable.map(token => {
>>> url.headers.set('Authorization', 'Bearer ' + token);
>>> return url;
>>> }).concatMap(request => super.request(request));
>>> }
>>> }
>>>
>>> }
>>>