AzureAD/azure-activedirectory-library-for-python

acquire_token_with_device_code never times out

HughGrovesArup opened this issue · 2 comments

Is there a way to get acquire_token_with_device_code to timeout? This code may potentially get buried where a user cannot see the prompt, and after a certain period I would like the function to timeout and throw an exception rather than just wait forever.

Greetings @HughGrovesArup

I reviewed the code behind this, and to me it seems like it could use as an additional optional parameter. The amount of time it spends polling for the user response will always be to the expiry and I'm unsure of how that is set on the AAD side (if it's even exposed). There is a method to cancel the polling; but it's not exposed to you when you call the acquire_token_with_device_code because it creates a new Oauth context internally.

I need to setup some tests in my own tenant; but I can see if they'll allow a push to dev with this. I don't think it would break anything as we'd keep the functionality the same; just allow for an optional timeout to the polling to be passed. I'd say adding 3-4 lines and an option parameter in two places.

There is a method cancel_request_to_get_token_with_device_code() to cancel the polling, however you would probably need a different thread to run it for you to reclaim the main thread blocked by acquire_token_with_device_code(). That is why personally I am not a fan of the blocking behavior of acquire_token_with_device_code(). I would rather have it probe once and return immediately, and let the app developer to decide whether/how they do the polling by an old school loop.

For what it's worth, now we have ADAL Python's successor, MSAL Python, which has a better Device Flow api model, initiate_device_flow() and acquire_token_by_device_flow(). The latter would still block by default (to mimic the ADAL Python behavior), and there is not even an explicit cancel_it(...) function. So how to cancel it in MSAL Python? As explicitly described in its doc, you modify its expires_at key (probably still from another thread). This new model at least gives you a way to customize the timeout behavior, so you can actually do the "non-block, return immediately, let me control the loop behavior" style if you prefer. Give it a shot.