Skip to content
This repository has been archived by the owner on May 5, 2023. It is now read-only.

ms-rest-azure.interactiveLogin callback always returns 'authorization_pending' error (in React Electron) #2002

Closed
christopheranderson opened this issue Dec 14, 2016 · 5 comments

Comments

@christopheranderson
Copy link

Issue:

When I call interactiveLogin, my callback is almost immediately called and it's given an error: authorization_pending.

This seemed strange to me, because it seems like it normally waits around for a bit when I'm doing a normal Node application, but I'm doing an Electron application and this call is actually taking place in a React component. I dove down through adal-node code, etc., but it doesn't look like they handle retry/etc. I felt like maybe this method should be attempting to retry for me.

Workaround:

I decided the way of getting around this for now is to add retry, so I ended up modifying interactive login to have retry baked into the acquireTokenWithDeviceCode step. Not necessarily the cleanest code, but it works now. :)

  // will retry until a non-pending error is returned or credentials are returned.
  var tryAcquireToken = function (userCodeResponse, callback) {
      self.context.acquireTokenWithDeviceCode(self.environment.activeDirectoryResourceId, self.clientId, userCodeResponse, function (err, tokenResponse) {
        if (err) {
          if(err.error === 'authorization_pending'){
            setTimeout(()=>{
              tryAcquireToken(userCodeResponse, callback);
            }, 1000);
            return
          } else {
            return callback(err);
          }
        }
        self.username = tokenResponse.userId;
        self.authorizationScheme = tokenResponse.tokenType;
        return callback(null);
      });
  }

  async.waterfall([
    //acquire usercode
    function (callback) {
      self.context.acquireUserCode(self.environment.activeDirectoryResourceId, self.clientId, self.language, function (err, userCodeResponse) {
        if (err) return callback(err);
        if (self.userCodeResponseLogger) {
          self.userCodeResponseLogger(userCodeResponse.message);
        } else {
          console.log(userCodeResponse.message);
        }
        return callback(null, userCodeResponse);
      });
    },
    //acquire token with device code and set the username to userId received from tokenResponse.
    tryAcquireToken,

/* nothing else changed from here... */

Not entirely sure if supporting Electron is actually important for ya'll. I'll likely just create a fork or a custom library for my purposes. I also had to create a custom version of adal-node which didn't read in the package.json from a relative directory. Just thought I'd raise this here since it did take a good couple of hours out of my day.

@amarzavery
Copy link
Contributor

I am not able to understand why would the callback immediately return. The grunt work is done by adal-node. The code that we have is a simple wrapper on it. adal-node does a blocking call for interactive login. adal-node should be handling the retry scenario correctly (if that is indeed a valid use case).

@cglong
Copy link
Member

cglong commented Aug 25, 2017

Just to +1 this, we saw this issue in a command-line Node based app as well. As soon as the message was printed to the console, the callback will immediately return with an authorization_pending message like @christopheranderson.

@daniel-oster
Copy link

daniel-oster commented Sep 27, 2017

I have the same issue trying to use interactive login. Digging around a bit I found that azure package brought in an old async library (v0.9) that was not able to parse the options object passed to the retry function. So we ended up retrying 5 times with no delay (default behavior)
I updated the async package and at least it blocks and wait for the interactive login now, what else breaks, I do not know..

@amarzavery
Copy link
Contributor

Ah I see. We will investigate further by bumping the version of async. If everything passes then we will take a dependency on newer version of async.
Btw, We are working towards creating an isomorphic js library that works in node.js environment and browser too. We have created a new library called ms-rest-nodeauth that focuses on node.js based authentication. This library does not use async library. It is written in typescript with latest ES6 and ES7 features (async/await, promises, etc.). It also supports callback for backwards compatibility. Give it a try and let us know if you have any issues with that.

@amarzavery
Copy link
Contributor

amarzavery commented Sep 29, 2017

Update: A newer version of "ms-rest-azure": "2.3.5" has been published which takes an explicit dependency on async version 2.5.0 and has the retry logic baked into it. Hope this should resolve the issue. Let us know if you find more issues.

@amarzavery amarzavery mentioned this issue Sep 29, 2017
14 tasks
amarzavery added a commit to amarzavery/azure-sdk-for-node that referenced this issue Sep 29, 2017
ramijarrar added a commit to fractal-code/meteor-azure that referenced this issue Oct 17, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants