sureshchahal / angular2-adal

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

AuthHttp is not passing along Authorization header #68

Open jderus opened 7 years ago

jderus commented 7 years ago

I am using version 2.0.0 of this lib. I am setting AuthHttp as a provider in app.module. I am also specifying AuthHttp in the constructor of the angular service that makes calls to an external webApi. Eg:

 constructor(private http: AuthHttp) {

I am not seeing the auth token in the header. What am I doing wrong, or missing?

fume commented 7 years ago

If your api is on a different domain (aka CORS request) you must specify the endpoints in the adal configuration. Please post an example of your code so we can help you.

jderus commented 7 years ago

Yeah, it is a different domain, so that is likely it.

I am just unclear what I need to set, or if I configured something else wrong. I thought I read somewhere on here that I just needed to switch to AuthHttp and this should handle the token refresh case, but I could have missed something.

Simplified gist of code below.

App.Module:

@NgModule({
    declarations: [ AppComponent,HomeComponent],
    imports: [BrowserModule, FormsModule, HttpModule],
    providers: [ MyService, AdalService, SecretService, AuthHttp],
    bootstrap: [AppComponent]
})
export class AppModule {
    constructor( private adalService: AdalService, private secretService: SecretService){
        this.adalService.init(this.secretService.adalConfig);

        this.adalService.handleWindowCallback();
        this.adalService.getUser();
        console.log('Init auth...');

        if (!this.adalService.userInfo.isAuthenticated) {
            console.log('Not logged in.');
            this.adalService.login();
        }
        else {
            console.log('Logged in: ' + this.adalService.userInfo.userName);
            console.log('Token:' + this.adalService.getCachedToken(this.secretService.adalConfig.clientId));
        }
    }
}

SecretService:

import { Injectable } from '@angular/core';

@Injectable()
export class SecretService {
    public get adalConfig(): any {
        return {
        tenant: 'xxx.onmicrosoft.com',
        clientId: 'REDACTED',
        redirectUri: window.location.origin + '/',
        postLogoutRedirectUri: window.location.origin + '/'
        };
    }
}

MyService:

import { Http, Response, Headers,RequestOptions, RequestOptionsArgs } from '@angular/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { AuthHttp } from 'ng2-adal/dist/core';

@Injectable()
export class MyService {
  private url:string;

  constructor(private http: AuthHttp) {
        this.url = "https://anApiUrl";
  }

    public DoStuff = (input): Observable<any> => {
        let headers = new Headers({ 'Content-Type': 'application/X-www-form-urlencoded;charset=UTF-8' });
        let options = new RequestOptions({ headers: headers });

        let body = JSON.stringify({ foo: input.foo, bar:input.bar});

        return this.http.post(this.url+"?action=dostuff",body,options)
            .map((response: Response) => <any>response)
            .catch((error:any) => Observable.throw(error.json() || 'Server error'));
    }
}

I have also tried adding a mapping in SecretService. EG:

endpoints: { "http://localhost:4200" : "https://anApiUrl" }
fume commented 7 years ago

endpoints property of adalConfig should be in the following form:

endpoints:{
 'http://webapiurl/api/': 'aClientId'
}

so, in your case, you should change the SecretService as following:

import { Injectable } from '@angular/core'
@Injectable()
export class SecretService {
    public get adalConfig(): any {
        return {
        tenant: 'xxx.onmicrosoft.com',
        clientId: 'REDACTED',
        redirectUri: window.location.origin + '/',
        postLogoutRedirectUri: window.location.origin + '/',
        endpoints:{
            'http://whatever/api/' : 'theClientId'
        }
        };
    }
}

if you're on localhost, even a different port is considered as a CORS request so you need to specify the port as well in the endpoints object.

Check here: https://github.com/AzureAD/azure-activedirectory-library-for-js#getting-started for further info about CORS.

Let me know, ciao!

jderus commented 7 years ago

Yeah thanks :)

I think I got it all working now, and it came down to putting in endpoints like you said. I got it wrong a few times along the way though. Thanks for all the help.

From your original pointers I started digging in a little deeper. I ended up checking the source code of AuthHttp as well as the AD link you also shared. Seems like it will not attach a token if it cannot create a resource (line 58) ... by design. This happens without endpoints, or with "incorrect" endpoints in the config.

fume commented 7 years ago

Hey, happy that it's working now :)

@sureshchahal Guess this issue can be closed

NilendraSarathchandra commented 5 years ago

I implemented this but I get this error

StaticInjectorError(AppModule)[AuthHttp -> Http]: StaticInjectorError(Platform: core)[Auth HttpHttp]: NullInjectorError: No provider for Http! at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get