Skip to content

Commit ddfda00

Browse files
authored
[Identity] Refactor broker logic (#42375)
We want to attempt silent auth regardless of platform. If silent auth is not supported, MSAL will return an error response that we can propagate to the user. - `use_default_broker_account` applies on all platforms - If interactive fallback is disabled, then we won't attempt interactive login. - Browser-based fallback is still attempted on non-Windows/WSL environments (maintaining current behavior). Signed-off-by: Paul Van Eck <[email protected]>
1 parent 57b0c21 commit ddfda00

File tree

4 files changed

+54
-67
lines changed

4 files changed

+54
-67
lines changed

sdk/identity/azure-identity-broker/CHANGELOG.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
# Release History
22

3-
## 1.3.0b3 (Unreleased)
3+
## 1.3.0 (2025-08-07)
44

55
### Features Added
66

7-
### Breaking Changes
8-
9-
### Bugs Fixed
10-
11-
### Other Changes
7+
- Allow silent authentication attempts on all platforms. Previously, `use_default_broker_account=True` in `InteractiveBrowserBrokerCredential` only applied to Windows/WSL. ([#42375](https://github.com/Azure/azure-sdk-for-python/pull/42375))
128

139
## 1.3.0b2 (2025-07-17)
1410

sdk/identity/azure-identity-broker/azure/identity/broker/_browser.py

Lines changed: 49 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -88,79 +88,70 @@ def _request_token(self, *scopes: str, **kwargs: Any) -> Dict:
8888
claims = kwargs.get("claims")
8989
pop = kwargs.get("pop")
9090
app = cast(msal.PublicClientApplication, self._get_app(**kwargs))
91-
port = self._parsed_url.port if self._parsed_url else None
9291
auth_scheme = None
9392
if pop:
9493
auth_scheme = msal.PopAuthScheme(
9594
http_method=pop["resource_request_method"], url=pop["resource_request_url"], nonce=pop["nonce"]
9695
)
97-
if sys.platform.startswith("win") or is_wsl():
98-
result = {}
99-
if self._use_default_broker_account:
100-
try:
101-
result = app.acquire_token_interactive(
102-
scopes=scopes_list,
103-
login_hint=self._login_hint,
104-
claims_challenge=claims,
105-
timeout=self._timeout,
106-
prompt=msal.Prompt.NONE,
107-
port=port,
108-
parent_window_handle=self._parent_window_handle,
109-
enable_msa_passthrough=self._enable_msa_passthrough,
110-
auth_scheme=auth_scheme,
111-
)
112-
if "access_token" in result:
113-
return result
114-
except socket.error:
115-
pass
11696

97+
result = {}
98+
99+
# Try silent authentication first if use_default_broker_account is enabled.
100+
if self._use_default_broker_account:
101+
try:
102+
result = self._attempt_token_acquisition(app, scopes_list, claims, auth_scheme, msal.Prompt.NONE)
103+
if "access_token" in result:
104+
return result
105+
except Exception as ex: # pylint: disable=broad-except
117106
if self._disable_interactive_fallback:
118-
self._check_result(result)
107+
raise CredentialUnavailableError(
108+
message="Failed to authenticate user with default broker account."
109+
) from ex
110+
111+
# Raise on error if interactive fallback is disabled.
112+
if self._disable_interactive_fallback:
113+
self._check_result(result)
119114

115+
# If we reach here, we need to try interactive authentication.
116+
if not self._disable_interactive_fallback:
120117
try:
121-
result = app.acquire_token_interactive(
122-
scopes=scopes_list,
123-
login_hint=self._login_hint,
124-
claims_challenge=claims,
125-
timeout=self._timeout,
126-
prompt="select_account",
127-
port=port,
128-
parent_window_handle=self._parent_window_handle,
129-
enable_msa_passthrough=self._enable_msa_passthrough,
130-
auth_scheme=auth_scheme,
118+
result = self._attempt_token_acquisition(
119+
app, scopes_list, claims, auth_scheme, msal.Prompt.SELECT_ACCOUNT
131120
)
132121
except socket.error as ex:
133122
raise CredentialUnavailableError(message="Couldn't start an HTTP server.") from ex
134-
135-
self._check_result(result)
136-
else:
137-
try:
138-
result = app.acquire_token_interactive(
139-
scopes=scopes_list,
140-
login_hint=self._login_hint,
141-
claims_challenge=claims,
142-
timeout=self._timeout,
143-
prompt="select_account",
144-
port=port,
145-
parent_window_handle=self._parent_window_handle,
146-
enable_msa_passthrough=self._enable_msa_passthrough,
147-
auth_scheme=auth_scheme,
148-
)
149-
except Exception: # pylint: disable=broad-except
150-
app = cast(msal.PublicClientApplication, self._disable_broker_on_app(**kwargs))
151-
result = app.acquire_token_interactive(
152-
scopes=scopes_list,
153-
login_hint=self._login_hint,
154-
claims_challenge=claims,
155-
timeout=self._timeout,
156-
prompt="select_account",
157-
port=port,
158-
parent_window_handle=self._parent_window_handle,
159-
enable_msa_passthrough=self._enable_msa_passthrough,
160-
)
123+
except Exception as ex: # pylint: disable=broad-except
124+
# Fallback to non-broker app only on non-Windows/WSL platforms.
125+
if not (sys.platform.startswith("win") or is_wsl()):
126+
app = cast(msal.PublicClientApplication, self._disable_broker_on_app(**kwargs))
127+
result = self._attempt_token_acquisition(app, scopes_list, claims, None, msal.Prompt.SELECT_ACCOUNT)
128+
else:
129+
raise CredentialUnavailableError(message="Failed to authenticate user with broker account.") from ex
161130
self._check_result(result)
131+
162132
return result
163133

134+
def _attempt_token_acquisition(
135+
self,
136+
app: msal.PublicClientApplication,
137+
scopes_list: list,
138+
claims: Any,
139+
auth_scheme: Any,
140+
prompt: str,
141+
) -> Dict:
142+
port = self._parsed_url.port if self._parsed_url else None
143+
return app.acquire_token_interactive(
144+
scopes=scopes_list,
145+
login_hint=self._login_hint,
146+
claims_challenge=claims,
147+
timeout=self._timeout,
148+
prompt=prompt,
149+
port=port,
150+
parent_window_handle=self._parent_window_handle,
151+
enable_msa_passthrough=self._enable_msa_passthrough,
152+
auth_scheme=auth_scheme,
153+
)
154+
164155
def _check_result(self, result: Dict[str, Any]) -> None:
165156
if "access_token" not in result and "error_description" in result:
166157
if within_dac.get():

sdk/identity/azure-identity-broker/azure/identity/broker/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
# Copyright (c) Microsoft Corporation.
33
# Licensed under the MIT License.
44
# ------------------------------------
5-
VERSION = "1.3.0b3"
5+
VERSION = "1.3.0"

sdk/identity/azure-identity-broker/setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity-broker",
4242
keywords="azure, azure sdk",
4343
classifiers=[
44-
"Development Status :: 4 - Beta",
44+
"Development Status :: 5 - Production/Stable",
4545
"Programming Language :: Python",
4646
"Programming Language :: Python :: 3 :: Only",
4747
"Programming Language :: Python :: 3",
@@ -63,6 +63,6 @@
6363
python_requires=">=3.9",
6464
install_requires=[
6565
"azure-identity<2.0.0,>=1.18.0",
66-
"msal[broker]>=1.33.0b1,<2",
66+
"msal[broker]>=1.33.0,<2",
6767
],
6868
)

0 commit comments

Comments
 (0)