sureshchahal / angular2-adal

Angular 2 wrapper for adal.js
MIT License
41 stars 50 forks source link

Use Angular HttpClient #57

Open jraadt opened 7 years ago

jraadt commented 7 years ago

With the newly released HttpClient in Angular it allows for interceptors. It may be a better option to build an interceptor that checks if the request is an authenticated endpoint resource instead of using authHttp service.

Arikael commented 6 years ago

I put a little something together

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { AdalService } from 'ng2-adal/dist/services/adal.service';

export class HttpAdalInterceptor implements HttpInterceptor {

    constructor(private adalService: AdalService) {

    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        const resource = this.adalService.GetResourceForEndpoint(req.url);

        if (resource) {

            if (this.adalService.userInfo.isAuthenticated) {
                this.adalService.acquireToken(resource)
                    .flatMap((token: string) => {
                        const newReq = req.clone({headers: req.headers.set('Authorization', 'Bearer: ' + token)});

                        return next.handle(newReq).catch(this.handleError);
                    });
            }
            else {
                return Observable.throw(new Error('User Not Authenticated.'));
            }
        }
        else {

            return next.handle(req).catch(this.handleError);
        }

        return next.handle(req);
    }

    private handleError(error: any) {
        return Observable.throw(error);
    }
}

and you would register it like so (in your modules, providers array

{
            provide: HTTP_INTERCEPTORS,
            useClass: HttpAdalInterceptor,
            deps: [AdalService],
            multi: true
        }

Just be careful, if you use it like that every http request will be intercepted which means even requests for assets like images, css, json and such (even on the same domain, because that's how adal works) You would have to add for example ./assets to anonymousEndpoints in your adal config.

I'm still evaluating and testing the code, so use it at your own risk ;) But maybe somebody has inputs, ideas or improvements.

I'm not yet fully convinced if using an interceptor is the best way to do it. While it is a clean way to handle it you let loose some control over your http requests. Just have to remember to put every non protected url to your anonymousEndpoints array.

joaopgrassi commented 6 years ago

Yeah thinking a little bit more on it doesn't make much sense. In our case for instance, our SPA calls multiple endpoints, but only one of them needs a token from adfs. Listing endpoints doesn't seems like a good idea to me. For us what makes more sense is to create an AdalHttpClient that does the stuff. To call other endpoints, we just use normal HttpClient.