Skip to content

Commit 9c34873

Browse files
committed
Gracefully handle RuntimeError upfront
1 parent 6e91109 commit 9c34873

File tree

2 files changed

+54
-63
lines changed

2 files changed

+54
-63
lines changed

msal/application.py

Lines changed: 52 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -505,10 +505,17 @@ def __init__(
505505
isinstance(self, ConfidentialClientApplication) or self.client_credential)
506506
if is_confidential_app and allow_broker:
507507
raise ValueError("allow_broker=True is only supported in PublicClientApplication")
508-
self._enable_broker = bool(
509-
allow_broker and not is_confidential_app
510-
and sys.platform == "win32"
511-
and not self.authority.is_adfs and not self.authority._is_b2c)
508+
self._enable_broker = False
509+
if (allow_broker and not is_confidential_app
510+
and sys.platform == "win32"
511+
and not self.authority.is_adfs and not self.authority._is_b2c):
512+
try:
513+
from . import broker # Trigger Broker's initialization
514+
self._enable_broker = True
515+
except RuntimeError:
516+
logger.exception(
517+
"Broker is unavailable on this platform. "
518+
"We will fallback to non-broker.")
512519
logger.debug("Broker enabled? %s", self._enable_broker)
513520

514521
self.token_cache = token_cache or TokenCache()
@@ -1072,14 +1079,10 @@ def remove_account(self, account):
10721079
"""Sign me out and forget me from token cache"""
10731080
self._forget_me(account)
10741081
if self._enable_broker:
1075-
try:
1076-
from .broker import _signout_silently
1077-
except RuntimeError: # TODO: TBD
1078-
logger.debug("Broker is unavailable on this platform. Fallback to non-broker.")
1079-
else:
1080-
error = _signout_silently(self.client_id, account["local_account_id"])
1081-
if error:
1082-
logger.debug("_signout_silently() returns error: %s", error)
1082+
from .broker import _signout_silently
1083+
error = _signout_silently(self.client_id, account["local_account_id"])
1084+
if error:
1085+
logger.debug("_signout_silently() returns error: %s", error)
10831086

10841087
def _sign_out(self, home_account):
10851088
# Remove all relevant RTs and ATs from token cache
@@ -1312,22 +1315,18 @@ def _acquire_token_silent_from_cache_and_possibly_refresh_it(
13121315
return self._acquire_token_by_cloud_shell(scopes, data=data)
13131316

13141317
if self._enable_broker and account is not None and data.get("token_type") != "ssh-cert":
1315-
try:
1316-
from .broker import _acquire_token_silently
1317-
except RuntimeError: # TODO: TBD
1318-
logger.debug("Broker is unavailable on this platform. Fallback to non-broker.")
1319-
else:
1320-
response = _acquire_token_silently(
1321-
"https://{}/{}".format(self.authority.instance, self.authority.tenant),
1322-
self.client_id,
1323-
account["local_account_id"],
1324-
scopes,
1325-
claims=_merge_claims_challenge_and_capabilities(
1326-
self._client_capabilities, claims_challenge),
1327-
correlation_id=correlation_id,
1328-
**data)
1329-
if response: # The broker provided a decisive outcome, so we use it
1330-
return self._process_broker_response(response, scopes, data)
1318+
from .broker import _acquire_token_silently
1319+
response = _acquire_token_silently(
1320+
"https://{}/{}".format(self.authority.instance, self.authority.tenant),
1321+
self.client_id,
1322+
account["local_account_id"],
1323+
scopes,
1324+
claims=_merge_claims_challenge_and_capabilities(
1325+
self._client_capabilities, claims_challenge),
1326+
correlation_id=correlation_id,
1327+
**data)
1328+
if response: # The broker provided a decisive outcome, so we use it
1329+
return self._process_broker_response(response, scopes, data)
13311330

13321331
result = _clean_up(self._acquire_token_silent_by_finding_rt_belongs_to_me_or_my_family(
13331332
authority, self._decorate_scope(scopes), account,
@@ -1533,24 +1532,20 @@ def acquire_token_by_username_password(
15331532
claims = _merge_claims_challenge_and_capabilities(
15341533
self._client_capabilities, claims_challenge)
15351534
if self._enable_broker:
1536-
try:
1537-
from .broker import _signin_silently
1538-
except RuntimeError: # TODO: TBD
1539-
logger.debug("Broker is unavailable on this platform. Fallback to non-broker.")
1540-
else:
1541-
response = _signin_silently(
1542-
"https://{}/{}".format(self.authority.instance, self.authority.tenant),
1543-
self.client_id,
1544-
scopes, # Decorated scopes won't work due to offline_access
1545-
MSALRuntime_Username=username,
1546-
MSALRuntime_Password=password,
1547-
validateAuthority="no"
1548-
if self.authority._validate_authority is False
1549-
or self.authority.is_adfs or self.authority._is_b2c
1550-
else None,
1551-
claims=claims,
1552-
)
1553-
return self._process_broker_response(response, scopes, kwargs.get("data", {}))
1535+
from .broker import _signin_silently
1536+
response = _signin_silently(
1537+
"https://{}/{}".format(self.authority.instance, self.authority.tenant),
1538+
self.client_id,
1539+
scopes, # Decorated scopes won't work due to offline_access
1540+
MSALRuntime_Username=username,
1541+
MSALRuntime_Password=password,
1542+
validateAuthority="no"
1543+
if self.authority._validate_authority is False
1544+
or self.authority.is_adfs or self.authority._is_b2c
1545+
else None,
1546+
claims=claims,
1547+
)
1548+
return self._process_broker_response(response, scopes, kwargs.get("data", {}))
15541549

15551550
scopes = self._decorate_scope(scopes)
15561551
telemetry_context = self._build_telemetry_context(
@@ -1759,20 +1754,17 @@ def acquire_token_interactive(
17591754
"04f0c124-f2bc-4f59-8241-bf6df9866bbd", # Visual Studio
17601755
] and data.get("token_type") != "ssh-cert" # Work around a known issue as of PyMsalRuntime 0.8
17611756
)
1762-
try:
1763-
return self._acquire_token_interactive_via_broker(
1764-
scopes,
1765-
parent_window_handle,
1766-
enable_msa_passthrough,
1767-
claims,
1768-
data,
1769-
on_before_launching_ui,
1770-
prompt=prompt,
1771-
login_hint=login_hint,
1772-
max_age=max_age,
1773-
)
1774-
except RuntimeError: # TODO: TBD
1775-
logger.debug("Broker is unavailable on this platform. Fallback to non-broker.")
1757+
return self._acquire_token_interactive_via_broker(
1758+
scopes,
1759+
parent_window_handle,
1760+
enable_msa_passthrough,
1761+
claims,
1762+
data,
1763+
on_before_launching_ui,
1764+
prompt=prompt,
1765+
login_hint=login_hint,
1766+
max_age=max_age,
1767+
)
17761768

17771769
on_before_launching_ui(ui="browser")
17781770
telemetry_context = self._build_telemetry_context(

msal/broker.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010

1111
logger = logging.getLogger(__name__)
1212
try:
13-
import pymsalruntime # ImportError would be raised on unsupported platforms such as Windows 8
14-
# Its API description is available in site-packages/pymsalruntime/PyMsalRuntime.pyi
13+
import pymsalruntime # Its API description is available in site-packages/pymsalruntime/PyMsalRuntime.pyi
1514
pymsalruntime.register_logging_callback(lambda message, level: { # New in pymsalruntime 0.7
1615
pymsalruntime.LogLevel.TRACE: logger.debug, # Python has no TRACE level
1716
pymsalruntime.LogLevel.DEBUG: logger.debug,
@@ -26,7 +25,7 @@
2625
# https://github.com/AzureAD/microsoft-authentication-library-for-cpp/pull/2406/files
2726
raise ImportError( # TODO: Remove or adjust this line right before merging this PR
2827
'You need to install dependency by: pip install "msal[broker]>=1.20.0b1,<2"')
29-
# Other exceptions (possibly RuntimeError) would be raised if its initialization fails
28+
# It could throw RuntimeError when running on ancient versions of Windows
3029

3130

3231
class RedirectUriError(ValueError):

0 commit comments

Comments
 (0)