-1

I have the following 2 methods.

But in the get method that I'm overriding from the Http module, the authentication success callback is called after it has already executed the request and returned a response. This way it's adding the JWT token to the headers in the wrong order, and too late.

I'm not super knowledgeable with promises and observables.. But what can I do so that it actually waits for the callback to be done before executing the request and returning the response?

authenticate(authCompletedCallback, errorCallback) {
  let authContext = new Microsoft.ADAL.AuthenticationContext(AUTHORITY_URL);

  authContext.tokenCache.readItems().then((items) => {
    if (items.length > 0) {
        AUTHORITY_URL = items[0].authority;
        authContext = new Microsoft.ADAL.AuthenticationContext(AUTHORITY_URL);
    }

    // Attempt to authorize user silently.
    authContext
      .acquireTokenSilentAsync(RESOURCE_URL, CLIENT_ID)
      .then(authCompletedCallback, () => {
          // We require user credentials so trigger authentication dialog.
          authContext
            .acquireTokenAsync(RESOURCE_URL, CLIENT_ID, REDIRECT_URL)
            .then(authCompletedCallback, errorCallback);
      });
  });
}

get(url: string, options?: RequestOptionsArgs): Observable<Response> {
  this.authenticate((authResponse) => {
    // This is executed second.
    if (!options) {
      options = { headers: new Headers() };
    }

    options.headers.set('Authorization', 'Bearer ' + authResponse.accessToken);
  }, (err) => {
    alert(JSON.stringify(err));
  });

  // This is executed first.
  return super.get(url, options);
}
Kid Diamond
  • 2,232
  • 8
  • 37
  • 79
  • See http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Saravana May 02 '17 at 13:46

1 Answers1

1

You might want to make the get function return a promise, since the actual Response object shouldn't exist until after you have authenticated. It looks like you're overriding a method, though, so maybe instead you'll want to make a different method.

getWithAuthentication(url: string, options?: RequestOptionsArgs): Promise<Observable<Response>> {
 return new Promise((resolve, reject) => {
  this.authenticate((authResponse) => {
    if (!options) {
      options = { headers: new Headers() };
    }

    options.headers.set('Authorization', 'Bearer ' + authResponse.accessToken);
    let response = super.get(url, options);
    resolve(response);
  }, (err) => {
    alert(JSON.stringify(err));
    reject(err);
  });
 }
}
libertyernie
  • 2,590
  • 1
  • 17
  • 13