Skip to content

Commit 56e4b01

Browse files
committed
Change Regional Endpoint to require opt-in
1 parent c04e6ea commit 56e4b01

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

msal/application.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ def __init__(
286286
which you will later provide via one of the acquire-token request.
287287
288288
:param str azure_region:
289-
Added since MSAL Python 1.12.0.
289+
AAD provides regional endpoints for apps to opt in
290+
to keep their traffic remain inside that region.
290291
291292
As of 2021 May, regional service is only available for
292293
``acquire_token_for_client()`` sent by any of the following scenarios::
@@ -303,9 +304,7 @@ def __init__(
303304
304305
4. An app which already onboard to the region's allow-list.
305306
306-
MSAL's default value is None, which means region behavior remains off.
307-
If enabled, the `acquire_token_for_client()`-relevant traffic
308-
would remain inside that region.
307+
This parameter defaults to None, which means region behavior remains off.
309308
310309
App developer can opt in to a regional endpoint,
311310
by provide its region name, such as "westus", "eastus2".
@@ -331,6 +330,9 @@ def __init__(
331330
or provide a custom http_client which has a short timeout.
332331
That way, the latency would be under your control,
333332
but still less performant than opting out of region feature.
333+
334+
New in version 1.12.0.
335+
334336
:param list[str] exclude_scopes: (optional)
335337
Historically MSAL hardcodes `offline_access` scope,
336338
which would allow your app to have prolonged access to user's data.
@@ -492,17 +494,18 @@ def _build_telemetry_context(
492494
correlation_id=correlation_id, refresh_reason=refresh_reason)
493495

494496
def _get_regional_authority(self, central_authority):
495-
is_region_specified = bool(self._region_configured
496-
and self._region_configured != self.ATTEMPT_REGION_DISCOVERY)
497497
self._region_detected = self._region_detected or _detect_region(
498498
self.http_client if self._region_configured is not None else None)
499-
if (is_region_specified and self._region_configured != self._region_detected):
499+
if (self._region_configured != self.ATTEMPT_REGION_DISCOVERY
500+
and self._region_configured != self._region_detected):
500501
logger.warning('Region configured ({}) != region detected ({})'.format(
501502
repr(self._region_configured), repr(self._region_detected)))
502503
region_to_use = (
503-
self._region_configured if is_region_specified else self._region_detected)
504+
self._region_detected
505+
if self._region_configured == self.ATTEMPT_REGION_DISCOVERY
506+
else self._region_configured) # It will retain the None i.e. opted out
507+
logger.debug('Region to be used: {}'.format(repr(region_to_use)))
504508
if region_to_use:
505-
logger.info('Region to be used: {}'.format(repr(region_to_use)))
506509
regional_host = ("{}.r.login.microsoftonline.com".format(region_to_use)
507510
if central_authority.instance in (
508511
# The list came from https://github.com/AzureAD/microsoft-authentication-library-for-python/pull/358/files#r629400328

tests/test_e2e.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -791,16 +791,15 @@ class WorldWideRegionalEndpointTestCase(LabBasedTestCase):
791791
region = "westus"
792792
timeout = 2 # Short timeout makes this test case responsive on non-VM
793793

794-
def test_acquire_token_for_client_should_hit_regional_endpoint(self):
794+
def _test_acquire_token_for_client(self, configured_region, expected_region):
795795
"""This is the only grant supported by regional endpoint, for now"""
796796
self.app = get_lab_app( # Regional endpoint only supports confidential client
797797

798798
## FWIW, the MSAL<1.12 versions could use this to achieve similar result
799799
#authority="https://westus.login.microsoft.com/microsoft.onmicrosoft.com",
800800
#validate_authority=False,
801801
authority="https://login.microsoftonline.com/microsoft.onmicrosoft.com",
802-
azure_region=self.region, # Explicitly use this region, regardless of detection
803-
802+
azure_region=configured_region,
804803
timeout=2, # Short timeout makes this test case responsive on non-VM
805804
)
806805
scopes = ["https://graph.microsoft.com/.default"]
@@ -809,9 +808,11 @@ def test_acquire_token_for_client_should_hit_regional_endpoint(self):
809808
self.app.http_client, "post", return_value=MinimalResponse(
810809
status_code=400, text='{"error": "mock"}')) as mocked_method:
811810
self.app.acquire_token_for_client(scopes)
811+
expected_host = '{}.r.login.microsoftonline.com'.format(
812+
expected_region) if expected_region else 'login.microsoftonline.com'
812813
mocked_method.assert_called_with(
813-
'https://westus.r.login.microsoftonline.com/{}/oauth2/v2.0/token'.format(
814-
self.app.authority.tenant),
814+
'https://{}/{}/oauth2/v2.0/token'.format(
815+
expected_host, self.app.authority.tenant),
815816
params=ANY, data=ANY, headers=ANY)
816817
result = self.app.acquire_token_for_client(
817818
scopes,
@@ -820,6 +821,29 @@ def test_acquire_token_for_client_should_hit_regional_endpoint(self):
820821
self.assertIn('access_token', result)
821822
self.assertCacheWorksForApp(result, scopes)
822823

824+
def test_acquire_token_for_client_should_hit_global_endpoint_by_default(self):
825+
self._test_acquire_token_for_client(None, None)
826+
827+
def test_acquire_token_for_client_should_ignore_env_var_by_default(self):
828+
os.environ["REGION_NAME"] = "eastus"
829+
self._test_acquire_token_for_client(None, None)
830+
del os.environ["REGION_NAME"]
831+
832+
def test_acquire_token_for_client_should_use_a_specified_region(self):
833+
self._test_acquire_token_for_client("westus", "westus")
834+
835+
def test_acquire_token_for_client_should_use_an_env_var_with_short_region_name(self):
836+
os.environ["REGION_NAME"] = "eastus"
837+
self._test_acquire_token_for_client(
838+
msal.ConfidentialClientApplication.ATTEMPT_REGION_DISCOVERY, "eastus")
839+
del os.environ["REGION_NAME"]
840+
841+
def test_acquire_token_for_client_should_use_an_env_var_with_long_region_name(self):
842+
os.environ["REGION_NAME"] = "East Us 2"
843+
self._test_acquire_token_for_client(
844+
msal.ConfidentialClientApplication.ATTEMPT_REGION_DISCOVERY, "eastus2")
845+
del os.environ["REGION_NAME"]
846+
823847
@unittest.skipUnless(
824848
os.getenv("LAB_OBO_CLIENT_SECRET"),
825849
"Need LAB_OBO_CLIENT_SECRET from https://aka.ms/GetLabSecret?Secret=TodoListServiceV2-OBO")

0 commit comments

Comments
 (0)