Skip to content

Commit

Permalink
Adds dSTS authority (as if it were an oidc_authority)
Browse files Browse the repository at this point in the history
  • Loading branch information
rayluo committed Dec 20, 2024
1 parent 7b31756 commit b1b5e94
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
4 changes: 4 additions & 0 deletions msal/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import warnings
from threading import Lock
from typing import Optional # Needed in Python 3.7 & 3.8
from urllib.parse import urlparse
import os

from .oauth2cli import Client, JwtAssertionCreator
Expand Down Expand Up @@ -623,6 +624,9 @@ def __init__(
# Here the self.authority will not be the same type as authority in input
if oidc_authority and authority:
raise ValueError("You can not provide both authority and oidc_authority")
if isinstance(authority, str) and urlparse(authority).path.startswith(
"/dstsv2"): # dSTS authority's path always starts with "/dstsv2"
oidc_authority = authority # So we treat it as if an oidc_authority
try:
authority_to_use = authority or "https://{}/common/".format(WORLD_WIDE)
self.authority = Authority(
Expand Down
51 changes: 41 additions & 10 deletions tests/test_authority.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,32 +104,63 @@ def test_authority_with_path_should_be_used_as_is(self, oidc_discovery):
"authorization_endpoint": "https://contoso.com/authorize",
"token_endpoint": "https://contoso.com/token",
})
class TestOidcAuthority(unittest.TestCase):
class OidcAuthorityTestCase(unittest.TestCase):
authority = "https://contoso.com/tenant"

def setUp(self):
# setUp() gives subclass a dynamic setup based on their authority
self.oidc_discovery_endpoint = (
# MSAL Python always does OIDC Discovery,
# not to be confused with Instance Discovery
# Here the test is to confirm the OIDC endpoint contains no "/v2.0"
self.authority + "/.well-known/openid-configuration")

def test_authority_obj_should_do_oidc_discovery_and_skip_instance_discovery(
self, oidc_discovery, instance_discovery):
c = MinimalHttpClient()
a = Authority(None, c, oidc_authority_url="https://contoso.com/tenant")
a = Authority(None, c, oidc_authority_url=self.authority)
instance_discovery.assert_not_called()
oidc_discovery.assert_called_once_with(
"https://contoso.com/tenant/.well-known/openid-configuration", c)
oidc_discovery.assert_called_once_with(self.oidc_discovery_endpoint, c)
self.assertEqual(a.authorization_endpoint, 'https://contoso.com/authorize')
self.assertEqual(a.token_endpoint, 'https://contoso.com/token')

def test_application_obj_should_do_oidc_discovery_and_skip_instance_discovery(
self, oidc_discovery, instance_discovery):
app = msal.ClientApplication(
"id",
authority=None,
oidc_authority="https://contoso.com/tenant",
)
"id", authority=None, oidc_authority=self.authority)
instance_discovery.assert_not_called()
oidc_discovery.assert_called_once_with(
"https://contoso.com/tenant/.well-known/openid-configuration",
app.http_client)
self.oidc_discovery_endpoint, app.http_client)
self.assertEqual(
app.authority.authorization_endpoint, 'https://contoso.com/authorize')
self.assertEqual(app.authority.token_endpoint, 'https://contoso.com/token')


class DstsAuthorityTestCase(OidcAuthorityTestCase):
# Inherits OidcAuthority's test cases and run them with a dSTS authority
authority = ( # dSTS is single tenanted with a tenant placeholder
'https://test-instance1-dsts.dsts.core.azure-test.net/dstsv2/common')
authorization_endpoint = (
"https://some.url.dsts.core.azure-test.net/dstsv2/common/oauth2/authorize")
token_endpoint = (
"https://some.url.dsts.core.azure-test.net/dstsv2/common/oauth2/token")

@patch("msal.authority._instance_discovery")
@patch("msal.authority.tenant_discovery", return_value={
"authorization_endpoint": authorization_endpoint,
"token_endpoint": token_endpoint,
}) # We need to create new patches (i.e. mocks) for non-inherited test cases
def test_application_obj_should_accept_dsts_url_as_an_authority(
self, oidc_discovery, instance_discovery):
app = msal.ClientApplication("id", authority=self.authority)
instance_discovery.assert_not_called()
oidc_discovery.assert_called_once_with(
self.oidc_discovery_endpoint, app.http_client)
self.assertEqual(
app.authority.authorization_endpoint, self.authorization_endpoint)
self.assertEqual(app.authority.token_endpoint, self.token_endpoint)


class TestAuthorityInternalHelperCanonicalize(unittest.TestCase):

def test_canonicalize_tenant_followed_by_extra_paths(self):
Expand Down

0 comments on commit b1b5e94

Please sign in to comment.