Skip to content

Commit f994470

Browse files
committed
refactor auth module: support for azure env in ClientContext
1 parent 7bdab8f commit f994470

File tree

11 files changed

+62
-57
lines changed

11 files changed

+62
-57
lines changed

examples/auth/gcc_high.py

+4-22
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
Microsoft Graph for US Government L4: https://graph.microsoft.us
55
"""
66

7-
import msal
8-
7+
from office365.azure_env import AzureEnvironment
98
from office365.graph_client import GraphClient
109
from tests import (
1110
test_client_id,
@@ -14,24 +13,7 @@
1413
test_user_principal_name,
1514
)
1615

17-
18-
def acquire_token():
19-
authority_url = "https://login.microsoftonline.us/{0}".format(test_tenant)
20-
21-
app = msal.ConfidentialClientApplication(
22-
authority=authority_url,
23-
client_id=test_client_id,
24-
client_credential=test_client_secret,
25-
)
26-
return app.acquire_token_for_client(scopes=["https://graph.microsoft.us/.default"])
27-
28-
29-
def construct_request(request):
30-
request.url = request.url.replace(
31-
"https://graph.microsoft.com", "https://graph.microsoft.us"
32-
)
33-
34-
35-
client = GraphClient(acquire_token)
36-
client.pending_request().beforeExecute += construct_request
16+
client = GraphClient(
17+
tenant=test_tenant, environment=AzureEnvironment.USGovernmentHigh
18+
).with_client_secret(test_client_id, test_client_secret)
3719
messages = client.users[test_user_principal_name].messages.get().execute_query()

examples/auth/sharepoint/register_apponly.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,16 @@
1616
1717
"""
1818

19+
from office365.directory.applications.app_ids import MsAppIds
1920
from office365.graph_client import GraphClient
20-
from tests import test_client_id, test_password, test_tenant, test_username
21+
from tests import test_client_id, test_client_secret, test_tenant
2122

22-
admin_client = GraphClient(tenant=test_tenant).with_username_and_password(
23-
test_client_id, test_username, test_password
23+
client = GraphClient(tenant=test_tenant).with_client_secret(
24+
test_client_id, test_client_secret
2425
)
26+
# client = GraphClient(tenant=test_tenant).with_token_interactive(test_client_id)
27+
resource = client.service_principals.get_by_app_id(
28+
MsAppIds.Office_365_SharePoint_Online
29+
)
30+
app = client.applications.get_by_app_id(test_client_id)
31+
resource.grant_application_permissions(app, "Sites.FullControl.All").execute_query()

examples/sharepoint/auth_app_only.py

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
The example demonstrates how to use SharePoint App-Only principal (second option)
1717
1818
https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azureacs
19+
20+
Notice:
21+
Starting April 2, 2026, Azure Access Control service (ACS) usage will be retired for SharePoint in Microsoft 365
22+
and users will no longer be able to create or use Azure ACS principals to access SharePoint.
23+
Learn more about the [Access Control retirement](https://aka.ms/retirement/acs/support)
1924
"""
2025

2126
from office365.sharepoint.client_context import ClientContext

examples/sharepoint/auth_app_principal_aad.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from office365.runtime.auth.token_response import TokenResponse
22
from office365.sharepoint.client_context import ClientContext
3-
from tests import settings, test_site_url
3+
from tests import test_client_id, test_client_secret, test_team_site_url, test_tenant
44

55
"""
66
Important: for Application authenticated against Azure AD blade, calling SharePoint v1 API endpoint when
@@ -20,22 +20,20 @@
2020

2121

2222
def acquire_token():
23-
authority_url = "https://login.microsoftonline.com/{0}".format(
24-
settings.get("default", "tenant")
25-
)
23+
authority = "https://login.microsoftonline.com/{0}".format(test_tenant)
2624
import msal
2725

2826
app = msal.ConfidentialClientApplication(
29-
authority=authority_url,
30-
client_id=settings.get("client_credentials", "client_id"),
31-
client_credential=settings.get("client_credentials", "client_secret"),
27+
authority=authority,
28+
client_id=test_client_id,
29+
client_credential=test_client_secret,
3230
)
3331
token_json = app.acquire_token_for_client(
3432
scopes=["https://mediadev8.sharepoint.com/.default"]
3533
)
3634
return TokenResponse.from_json(token_json)
3735

3836

39-
ctx = ClientContext(test_site_url).with_access_token(acquire_token)
37+
ctx = ClientContext(test_team_site_url).with_access_token(acquire_token)
4038
target_web = ctx.web.get().execute_query()
4139
print(target_web.url)

examples/sharepoint/auth_certificate.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
https://github.com/vgrem/Office365-REST-Python-Client/wiki/How-to-connect-to-SharePoint-Online-with-certificate-credentials
1313
"""
1414

15-
import os
16-
1715
from office365.sharepoint.client_context import ClientContext
1816
from tests import (
1917
test_cert_thumbprint,
@@ -26,7 +24,7 @@
2624
"tenant": test_tenant,
2725
"client_id": test_client_id,
2826
"thumbprint": test_cert_thumbprint,
29-
"cert_path": "{0}/../selfsignkey.pem".format(os.path.dirname(__file__)),
27+
"cert_path": "./selfsigncert.pem",
3028
}
3129
ctx = ClientContext(test_site_url).with_client_certificate(**cert_credentials)
3230
current_web = ctx.web.get().execute_query()

office365/azure_env.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ class AzureEnvironment(object):
4848
@classmethod
4949
def get_graph_authority(cls, env):
5050
# type: (str) -> str
51-
return cls._authority_endpoints.get(env)["graph"]
51+
return cls._authority_endpoints.get(env, cls._authority_endpoints["Global"])[
52+
"graph"
53+
]
5254

5355
@classmethod
5456
def get_login_authority(cls, env):
5557
# type: (str) -> str
56-
return cls._authority_endpoints.get(env)["login"]
58+
return cls._authority_endpoints.get(env, cls._authority_endpoints["Global"])[
59+
"login"
60+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class MsAppIds:
2+
"""Enum for commonly used Microsoft application IDs."""
3+
4+
Office_365_SharePoint_Online = "00000003-0000-0ff1-ce00-000000000000"
5+
6+
Office_365_Exchange_Online = "00000002-0000-0ff1-ce00-000000000000"

office365/runtime/auth/authentication_context.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from typing_extensions import Required, Self, TypedDict
66

7+
from office365.azure_env import AzureEnvironment
78
from office365.runtime.auth.client_credential import ClientCredential
89
from office365.runtime.auth.providers.acs_token_provider import ACSTokenProvider
910
from office365.runtime.auth.providers.saml_token_provider import SamlTokenProvider
@@ -31,13 +32,11 @@ def _get_authorization_header(token):
3132
class AuthenticationContext(object):
3233
"""Authentication context for SharePoint Online/OneDrive For Business"""
3334

34-
def __init__(
35-
self, url, environment="commercial", allow_ntlm=False, browser_mode=False
36-
):
35+
def __init__(self, url, environment=None, allow_ntlm=False, browser_mode=False):
3736
"""
3837
:param str url: SharePoint absolute web or site Url
3938
:param str environment: The Office 365 Cloud Environment endpoint used for authentication
40-
defaults to 'commercial'.
39+
defaults to 'Azure Global'.
4140
:param bool allow_ntlm: Flag indicates whether NTLM scheme is enabled. Disabled by default
4241
:param bool browser_mode: Allow browser authentication
4342
"""
@@ -80,7 +79,9 @@ def with_client_certificate(
8079
private_key = f.read()
8180

8281
def _acquire_token():
83-
authority_url = "https://login.microsoftonline.com/{0}".format(tenant)
82+
authority_url = "{0}/{1}".format(
83+
AzureEnvironment.get_login_authority(self._environment), tenant
84+
)
8485
credentials = {
8586
"thumbprint": thumbprint,
8687
"private_key": private_key,
@@ -119,7 +120,9 @@ def _acquire_token():
119120

120121
app = msal.PublicClientApplication(
121122
client_id,
122-
authority="https://login.microsoftonline.com/{0}".format(tenant),
123+
authority="{0}/{1}".format(
124+
AzureEnvironment.get_login_authority(self._environment), tenant
125+
),
123126
client_credential=None,
124127
)
125128
result = app.acquire_token_interactive(scopes=scopes)
@@ -145,7 +148,9 @@ def _acquire_token():
145148

146149
app = msal.PublicClientApplication(
147150
client_id,
148-
authority="https://login.microsoftonline.com/{0}".format(tenant),
151+
authority="{0}/{1}".format(
152+
AzureEnvironment.get_login_authority(self._environment), tenant
153+
),
149154
client_credential=None,
150155
)
151156

office365/runtime/auth/providers/acs_token_provider.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@
33
import requests
44

55
import office365.logger
6+
from office365.azure_env import AzureEnvironment
67
from office365.runtime.auth.authentication_provider import AuthenticationProvider
78
from office365.runtime.auth.token_response import TokenResponse
89
from office365.runtime.compat import urlparse
910
from office365.runtime.http.request_options import RequestOptions
1011

1112

1213
class ACSTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
13-
def __init__(self, url, client_id, client_secret, environment="commercial"):
14+
def __init__(self, url, client_id, client_secret, environment=None):
1415
"""
1516
Provider to acquire the access token from a Microsoft Azure Access Control Service (ACS)
1617
1718
:param str client_id: The OAuth client id of the calling application.
1819
:param str client_secret: Secret string that the application uses to prove its identity when requesting a token
1920
:param str url: SharePoint web or site url
2021
:param str environment: The Office 365 Cloud Environment endpoint used for authentication
21-
defaults to 'commercial'.
22+
defaults to 'Azure Global'.
2223
"""
2324
self.url = url
2425
self.redirect_url = None
@@ -61,9 +62,7 @@ def _get_app_only_access_token(self, target_host, target_realm):
6162
self.SharePointPrincipal, target_host, target_realm
6263
)
6364
principal_id = self.get_formatted_principal(self._client_id, None, target_realm)
64-
sts_url = self.get_security_token_service_url(
65-
target_realm, environment=self._environment
66-
)
65+
sts_url = self.get_security_token_service_url(target_realm)
6766
oauth2_request = {
6867
"grant_type": "client_credentials",
6968
"client_id": principal_id,
@@ -96,11 +95,12 @@ def get_formatted_principal(principal_name, host_name, realm):
9695
return "{0}/{1}@{2}".format(principal_name, host_name, realm)
9796
return "{0}@{1}".format(principal_name, realm)
9897

99-
@staticmethod
100-
def get_security_token_service_url(realm, environment):
101-
# type: (str, str) -> str
102-
if environment == "GCCH":
103-
return "https://login.microsoftonline.us/{0}/tokens/OAuth/2".format(realm)
98+
def get_security_token_service_url(self, realm):
99+
# type: (str) -> str
100+
if self._environment:
101+
return "{0}/{1}/tokens/OAuth/2".format(
102+
AzureEnvironment.get_login_authority(self._environment), realm
103+
)
104104
else:
105105
return (
106106
"https://accounts.accesscontrol.windows.net/{0}/tokens/OAuth/2".format(

office365/sharepoint/client_context.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def __init__(
4545
self,
4646
base_url,
4747
auth_context=None,
48-
environment="commercial",
48+
environment=None,
4949
allow_ntlm=False,
5050
browser_mode=False,
5151
):

tests/settings.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ client_id = 4b7eb3df-afc3-4b7d-ae1d-629f22a3fe42
1919
client_secret = --secret--
2020

2121
[certificate_credentials]
22-
thumbprint = 3EF4F1233C1FC43D681A6E01B02EB99393C7C951
22+
thumbprint = 18920629918EE14DC0937791358971497E952A77
2323

2424
[users]
2525
tenant_prefix = mediadev8

0 commit comments

Comments
 (0)