Repository navigation
InteractiveBrowserCredential does not hand over to next credential in chain if no browser is supported #32276
Description
- Package Name: azure.identity
- Package Version: 1.14.0
- Operating System: Linux
- Python Version: 3.11.5
Describe the bug
We use a ChainedTokenCredential containing an InteractiveBrowserCredential and a DeviceCodeCredential to authenticate to Azure. We use this to authenticate on jupyterhub, allowing us to run code locally as well as on a remote kernel. In version 1.12.0, this worked beautifully, but since upgrading to v1.14.0, this now breaks on a remote host: the InteractiveBrowserCredential never seems to hand over to the DeviceCodeCredential if no browser is found, instead raising an exception.
To Reproduce
Run the following on a machine without browser available:
import azure.identity
import azure.storage.blob as az_blob
import datetime
cred = azure.identity.ChainedTokenCredential(
azure.identity.InteractiveBrowserCredential(timeout=1),
azure.identity.DeviceCodeCredential(),
)
client = az_blob.BlobServiceClient(
account_url=f"https://storage_account.blob.core.windows.net",
credential=cred
)
client.get_user_delegation_key(
key_start_time=datetime.datetime.now(tz=datetime.UTC),
key_expiry_time=datetime.datetime.now(tz=datetime.UTC) + datetime.timedelta(minutes=5)
)(Here I'm just getting a user delegation key to force authentication. I'm sure there's a simpler way to do this that I'm unaware of.)
This prints warnings about no browser being found, and eventually fails with an exception
(azure.core.exceptions.ClientAuthenticationError: ChainedTokenCredential failed to retrieve a token from the included credentials.).
Expected behavior
If authenticating interactively fails, I expect the ChainedTokenCredential to hand over to the next Credential in the chain. This did happen in v1.12.0, and the code above in this version yields the following output:
InteractiveBrowserCredential.get_token failed: Failed to open a browser
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code xxxxxxxxxx to authenticate.
almost immediately, as soon as no browser is found.
Additional context
The expected behaviour can be emulated by wrapping the InteractiveBrowserCredential in another class that raises a CredentialUnavailableError if authentication fails:
class InteractiveBrowserCredentialWrapper(azure.identity.InteractiveBrowserCredential):
def get_token(self, *args, **kwargs):
try:
return super().get_token(*args, **kwargs)
except azure.core.exceptions.ClientAuthenticationError as e:
raise azure.identity._exceptions.CredentialUnavailableError() from e
cred = azure.identity.ChainedTokenCredential(
InteractiveBrowserCredentialWrapper(timeout=1),
azure.identity.DeviceCodeCredential(),
)
client = az_blob.BlobServiceClient(
account_url=f"https://spaceintelliprojects.blob.core.windows.net",
credential=cred
)
sign_key = client.get_user_delegation_key(
key_start_time=datetime.datetime.now(tz=datetime.UTC), key_expiry_time=datetime.datetime.now(tz=datetime.UTC) + datetime.timedelta(minutes=5)
)However, this still waits for the InteractiveBrowserCredential to time out, which isn't ideal.
If this is now the preferred behaviour, it would be nice to have the behaviour on no browser being available being configurable, so backward compatibility can be maintained.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
xiangyan99 commentedon Sep 28, 2023
Thanks for reporting the issue.
We will investigate ASAP.
xkszltl commentedon Oct 3, 2023
We're hitting the same issue.
Was on 1.10.0 and it would quickly give up when no browser is available.
xkszltl commentedon Oct 3, 2023
Same issue found in both 1.14.0 and 1.13.0.
Confirmed 1.12.0 is fine
xiangyan99 commentedon Oct 17, 2023
Thank you.
The issue is fixed and will be available in next release.
github-actions commentedon Oct 17, 2023
Hi Stig (@stviaene-si). Thank you for opening this issue and giving us the opportunity to assist. We believe that this has been addressed. If you feel that further discussion is needed, please add a comment with the text "/unresolve" to remove the "issue-addressed" label and continue the conversation.
github-actions commentedon Oct 24, 2023
Hi Stig (@stviaene-si), since you haven’t asked that we
/unresolvethe issue, we’ll close this out. If you believe further discussion is needed, please add a comment/unresolveto reopen the issue.