Azure / azure-sdk-for-python

This repository is for active development of the Azure SDK for Python. For consumers of the SDK we recommend visiting our public developer docs at https://learn.microsoft.com/python/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-python.
MIT License
4.63k stars 2.83k forks source link

azure.identity.InteractiveBrowserCredential has stopped working in azure-identity 1.13.0 #31030

Closed PL-SalvadorFandino closed 1 year ago

PL-SalvadorFandino commented 1 year ago

Describe the bug InteractiveBrowserCredential with client credentials which was working in version 1.12, has stopped working in 1.13

To Reproduce

Sample script:

tenant_id="15de..."
client_id="fd41..."
client_secret="Hpl..."

from azure.identity import InteractiveBrowserCredential

cred = InteractiveBrowserCredential(tenant_id=tenant_id,
                                    client_id=client_id,
                                    client_credential=client_secret,
                                    prompt="login",
                                    redirect_uri="http://localhost:8082")
cred.authenticate(scopes=["https://graph.microsoft.com/.default"])

print("OK.")

Expected behavior Authentication succeds.

Screenshots

InteractiveBrowserCredential.get_token failed: Authentication failed: 'ConfidentialClientApplication' object has no attribute 'acquire_token_interactive'
Traceback (most recent call last):
  File "/home/salva/g/pl/PL-TEC-Reporting/ve/lib/python3.10/site-packages/azure/identity/_internal/decorators.py", line 74, in wrapper
    return fn(*args, **kwargs)
  File "/home/salva/g/pl/PL-TEC-Reporting/ve/lib/python3.10/site-packages/azure/identity/_credentials/browser.py", line 83, in _request_token
    result = app.acquire_token_interactive(
AttributeError: 'ConfidentialClientApplication' object has no attribute 'acquire_token_interactive'. Did you mean: 'acquire_token_on_behalf_of'?

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/salva/g/pl/PL-TEC-Reporting/../PL-TEC-PLPipes/3d-party-bug-reports/interactive_browser_credentials.py", line 17, in <module>
    cred.authenticate(scopes=["https://graph.microsoft.com/.default"])
  File "/home/salva/g/pl/PL-TEC-Reporting/ve/lib/python3.10/site-packages/azure/identity/_internal/interactive.py", line 187, in authenticate
    _ = self.get_token(*scopes, _allow_prompt=True, **kwargs)
  File "/home/salva/g/pl/PL-TEC-Reporting/ve/lib/python3.10/site-packages/azure/identity/_internal/interactive.py", line 144, in get_token
    result = self._request_token(*scopes, **kwargs)
  File "/home/salva/g/pl/PL-TEC-Reporting/ve/lib/python3.10/site-packages/azure/identity/_internal/decorators.py", line 79, in wrapper
    raise_from(auth_error, ex)
  File "<string>", line 3, in raise_from
azure.core.exceptions.ClientAuthenticationError: Authentication failed: 'ConfidentialClientApplication' object has no attribute 'acquire_token_interactive'

Additional context

kashifkhan commented 1 year ago

Thank you for the detailed explanation & repro @PL-SalvadorFandino . We will investigate & get back to you asap.

pvaneck commented 1 year ago

Hey, thanks for reaching out.

After the 1.12 release there was a change to what MSAL client application method was used when handling this credential.

From what I understand, users shouldn't need to pass in the client_secret if using InteractiveBrowserCredential. If trying to authenticate with tenant_id, client_id, and client_secret then ClientSecretCredential is probably the best option.

And I believe the kwarg client_credential wasn't meant for end-user usage. The usage of this kwarg seems to have the unintended consequence of instantiating the incorrect underyling MSAL client application (i.e. ConfidentialClientApplication instead of PublicClientApplication).

Does your app still work if you remove the client_credential argument when instantiating InteractiveBrowserCredential?

PL-SalvadorFandino commented 1 year ago

After removing the client_credential argument from the call, I get the following error:

InteractiveBrowserCredential.get_token failed: AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.
Trace ID: 93fb6a95-1fe3-4b12-8345-3f2e1da96500
Correlation ID: 2d18f9f0-346a-4983-8947-8c52f7ef482e
Timestamp: 2023-07-10 06:59:45Z
Traceback (most recent call last):
  File "/home/salva/g/pl/technical-office/PL-TEC-Reporting/../PL-TEC-PLPipes/interactive_browser_credentials.py", line 17, in <module>
    cred.authenticate(scopes=["https://graph.microsoft.com/.default"])
  File "/home/salva/g/pl/technical-office/PL-TEC-Reporting/ve/lib/python3.11/site-packages/azure/identity/_internal/interactive.py", line 187, in authenticate
    _ = self.get_token(*scopes, _allow_prompt=True, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/salva/g/pl/technical-office/PL-TEC-Reporting/ve/lib/python3.11/site-packages/azure/identity/_internal/interactive.py", line 144, in get_token
    result = self._request_token(*scopes, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/salva/g/pl/technical-office/PL-TEC-Reporting/ve/lib/python3.11/site-packages/azure/identity/_internal/decorators.py", line 74, in wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/home/salva/g/pl/technical-office/PL-TEC-Reporting/ve/lib/python3.11/site-packages/azure/identity/_credentials/browser.py", line 94, in _request_token
    raise ClientAuthenticationError(message=result.get("error_description"))
azure.core.exceptions.ClientAuthenticationError: AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.
Trace ID: 93fb6a95-1fe3-4b12-8345-3f2e1da96500
Correlation ID: 2d18f9f0-346a-4983-8947-8c52f7ef482e
Timestamp: 2023-07-10 06:59:45Z

MS Graph access control requires the double authentication, both the app and the user.

The user has rights to access particular resources but the the app also requires "functional" permissions. So, even if the user delegates his access rights to the app, the app still needs to be granted permissions to call the particular API functions it uses, and in order to get those rights it needs to authenticate.

xiangyan99 commented 1 year ago

Thank you for reporting the issue.

The fix is merged and will be ready in next release.