AzureAD / microsoft-authentication-library-for-python

Microsoft Authentication Library (MSAL) for Python makes it easy to authenticate to Microsoft Entra ID. General docs are available here https://learn.microsoft.com/entra/msal/python/ Stable APIs are documented here https://msal-python.readthedocs.io. Questions can be asked on www.stackoverflow.com with tag "msal" + "python".
https://stackoverflow.com/questions/tagged/azure-ad-msal+python
Other
754 stars 191 forks source link

`acquire_token_interactive` cannot open web browser on WSL2 + Ubuntu 22.04 #625

Closed jiasli closed 7 months ago

jiasli commented 7 months ago

Describe the bug acquire_token_interactive cannot open web browser on WSL2 + Ubuntu 22.04. The upstream issue is https://github.com/microsoft/WSL/issues/8892.

To Reproduce

$ az login
A web browser has been opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.
/usr/bin/xdg-open: 882: x-www-browser: not found
/usr/bin/xdg-open: 882: firefox: not found
/usr/bin/xdg-open: 882: iceweasel: not found
/usr/bin/xdg-open: 882: seamonkey: not found
/usr/bin/xdg-open: 882: mozilla: not found
/usr/bin/xdg-open: 882: epiphany: not found
/usr/bin/xdg-open: 882: konqueror: not found
/usr/bin/xdg-open: 882: chromium: not found
/usr/bin/xdg-open: 882: chromium-browser: not found
/usr/bin/xdg-open: 882: google-chrome: not found
/usr/bin/xdg-open: 882: www-browser: not found
/usr/bin/xdg-open: 882: links2: not found
/usr/bin/xdg-open: 882: elinks: not found
/usr/bin/xdg-open: 882: links: not found
/usr/bin/xdg-open: 882: lynx: not found
/usr/bin/xdg-open: 882: w3m: not found
xdg-open: no method available for opening 'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?...'

Additional context Windows Terminal supports Ctrl+Click to open hyperlinks, so the user can Ctrl+Click the URL after xdg-open: no method available for opening to open the web browser and the rest steps work as usual.

rayluo commented 7 months ago

Thanks for bringing this to our attention.

If the end user is aware that they are using "WSL2 + Ubuntu22.04", installing wslu package or setting up a proper BROWSER env var will allegedly work.

From Azure CLI's perspective, it is lucky that last line of error provides a visible URL:

xdg-open: no method available for opening 'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?...'

So, perhaps Azure CLI can reword the first line in your screenshot:

A web browser ~has been~ will be opened ~at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize~. Please continue ... If no web browser is available or if the web browser fails to open, you can manually open the link shown in an error message below, or use device code flow ...

bgavrilMS commented 7 months ago

Btw, MSAL.NET added support for several other tools for opening browser on Linux, apart from xdg-open: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/blob/main/src/client/Microsoft.Identity.Client/Platforms/netcore/NetCorePlatformProxy.cs#L236

Not sure it'll fix the issue here, as xdg-open does seem to exist on the box. But I wonder if wslview will work.

rayluo commented 7 months ago

@bgavrilMS , is there an MSAL .Net test app for @jiasli to test the MSAL .Net behavior and see if that helps?

Regardless, I do not think this is a bug. At least not in MSAL Python.

Python has a built-in module webbrowser which was designed and implemented to support multiple browsers. But in this case, not even a python -m webbrowser -t "https://www.python.org" would work, according to @jiasli 's report here. MSAL Python is designed and implemented to rely on Python's webbrowser behavior.

This was working before, so it feels like a regression on WSL.

Anyway, the "p2" and "bug" labels got my attention. @jiasli , you can ping me offline for an alternative solution, which will still be in the direction of my earlier suggestion of refining Azure CLI's error message. But I can tell you an undocumented API that would be triggered only when browser is unavailable.

jiasli commented 7 months ago

The Ubuntu 22.04 on my another computer doesn't have xdg-utils installed, or if I uninstall xdg-utils explicitly:

sudo apt remove xdg-utils

On Python 3.10, webbrowser.open returns False:

$ /usr/bin/python3 -V
Python 3.10.12
$ /usr/bin/python3 -c "import webbrowser; print(webbrowser.open('https://login.microsoftonline.com/'))"
False

This makes https://github.com/AzureAD/microsoft-authentication-library-for-python/commit/8d869173dc1fe5fc66de5421c16a1e832ab206e6 kick in, triggering the logic we added for Ubuntu 18.04 (https://github.com/AzureAD/microsoft-authentication-library-for-python/pull/333).

But on Python 3.11 (which Azure CLI 2.54.0 DEB package bundles), webbrowser.open returns True and prints an error:

$ /opt/az/bin/python3 -V
Python 3.11.5
$ /opt/az/bin/python3 -c "import webbrowser; print(webbrowser.open('https://login.microsoftonline.com/'))"
True
gio: https://login.microsoftonline.com/: Operation not supported

I can tell you an undocumented API that would be triggered only when browser is unavailable.

If you are referring to auth_uri_callback, it actually relies on _browse returning False:

https://github.com/AzureAD/microsoft-authentication-library-for-python/blob/37028160ec815ad52929e64aee3e9f879c025a36/msal/oauth2cli/authcode.py#L289-L311

but the tricky thing is that in my above examples, you can see webbrowser.open returns True but prints an error. This leaves MSAL no way to know it has failed to open the browser, so auth_uri_callback will never be hit.

jiasli commented 7 months ago

So, perhaps Azure CLI can reword the first line in your screenshot:

A web browser ~has been~ will be opened ~at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize~. Please continue ... If no web browser is available or if the web browser fails to open, you can manually open the link shown in an error message below, or use device code flow ...

  1. We can't delete the https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize as the user must know which tab in the browser is for login. The warning message was added back in https://github.com/Azure/azure-cli/pull/14505
  2. Currently, I prefer not to change the warning message specially for a WSL issue that will likely be fixed in the future.
rayluo commented 7 months ago

The Ubuntu 22.04 on my another computer doesn't have xdg-utils installed, or if I uninstall xdg-utils explicitly:

sudo apt remove xdg-utils

On Python 3.10, webbrowser.open returns False:

$ /usr/bin/python3 -V
Python 3.10.12
$ /usr/bin/python3 -c "import webbrowser; print(webbrowser.open('https://login.microsoftonline.com/'))"
False

This makes 8d86917 kick in, triggering the logic we added for Ubuntu 18.04 (#333).

But on Python 3.11 (which Azure CLI 2.54.0 DEB package bundles), webbrowser.open returns True and prints an error:

$ /opt/az/bin/python3 -V
Python 3.11.5
$ /opt/az/bin/python3 -c "import webbrowser; print(webbrowser.open('https://login.microsoftonline.com/'))"
True
gio: https://login.microsoftonline.com/: Operation not supported

I can tell you an undocumented API that would be triggered only when browser is unavailable.

If you are referring to auth_uri_callback, it actually relies on _browse returning False:

Thanks for your investigation, @jiasli !

Admittedly, Python's webbrowser.open() did not even document its return value. We just used it that way based on empirical observation.

Currently, I prefer not to change the warning message specially for a WSL issue that will likely be fixed in the future.

If necessary, MSAL Python could add a mechanism to return the full url via some callback, for downstream app to unconditionally print it, so that the end user would have a chance to know thus manually open it. But the user experience would be really bad, because the url is lengthy and being displayed all the time.

So, overall, I agree with your assessment that MSAL not changing the behaviors specially for an upstream WSL issue that will likely be fixed in the future.

Shall we close this issue (as Not Planned), then?

jiasli commented 7 months ago

Shall we close this issue (as Not Planned), then?

Well. That depends on you. I am opening this issue only for tracking purpose and increasing the visibility of https://github.com/microsoft/WSL/issues/8892. I also created one for Azure CLI: https://github.com/Azure/azure-cli/issues/27879.

rayluo commented 7 months ago

So, we already have a triage conclusion as above. Now, in terms of keep an issue open for indefinite time for tracking purpose, I think in this MSAL Repo we have been experimenting using Github Discussion Q&A for this kind of purpose. I'm converting this issue into a Q&A.