microsoft-agents-authentication-msal 0.9.0.dev6__tar.gz → 0.9.0.dev7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/PKG-INFO +2 -2
  2. microsoft_agents_authentication_msal-0.9.0.dev7/VERSION.txt +1 -0
  3. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents/authentication/msal/msal_auth.py +181 -168
  4. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents_authentication_msal.egg-info/PKG-INFO +2 -2
  5. microsoft_agents_authentication_msal-0.9.0.dev7/microsoft_agents_authentication_msal.egg-info/requires.txt +3 -0
  6. microsoft_agents_authentication_msal-0.9.0.dev6/VERSION.txt +0 -1
  7. microsoft_agents_authentication_msal-0.9.0.dev6/microsoft_agents_authentication_msal.egg-info/requires.txt +0 -3
  8. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/LICENSE +0 -0
  9. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/MANIFEST.in +0 -0
  10. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents/authentication/msal/__init__.py +0 -0
  11. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents/authentication/msal/errors/__init__.py +0 -0
  12. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents/authentication/msal/errors/error_resources.py +0 -0
  13. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents/authentication/msal/msal_connection_manager.py +0 -0
  14. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents_authentication_msal.egg-info/SOURCES.txt +0 -0
  15. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents_authentication_msal.egg-info/dependency_links.txt +0 -0
  16. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/microsoft_agents_authentication_msal.egg-info/top_level.txt +0 -0
  17. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/pyproject.toml +0 -0
  18. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/readme.md +0 -0
  19. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/setup.cfg +0 -0
  20. {microsoft_agents_authentication_msal-0.9.0.dev6 → microsoft_agents_authentication_msal-0.9.0.dev7}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-authentication-msal
3
- Version: 0.9.0.dev6
3
+ Version: 0.9.0.dev7
4
4
  Summary: A msal-based authentication library for Microsoft Agents
5
5
  Author: Microsoft Corporation
6
6
  License-Expression: MIT
@@ -15,7 +15,7 @@ Classifier: Operating System :: OS Independent
15
15
  Requires-Python: >=3.10
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: microsoft-agents-hosting-core==0.9.0.dev6
18
+ Requires-Dist: microsoft-agents-hosting-core==0.9.0.dev7
19
19
  Requires-Dist: msal>=1.34.0
20
20
  Requires-Dist: requests>=2.32.3
21
21
  Dynamic: license-file
@@ -25,6 +25,7 @@ from microsoft_agents.hosting.core import (
25
25
  AccessTokenProviderBase,
26
26
  AgentAuthConfiguration,
27
27
  )
28
+ from microsoft_agents.hosting.core.authorization.telemetry import spans
28
29
  from microsoft_agents.authentication.msal.errors import authentication_errors
29
30
 
30
31
  logger = logging.getLogger(__name__)
@@ -65,40 +66,48 @@ class MsalAuth(AccessTokenProviderBase):
65
66
  async def get_access_token(
66
67
  self, resource_url: str, scopes: list[str], force_refresh: bool = False
67
68
  ) -> str:
68
- logger.debug(
69
- f"Requesting access token for resource: {resource_url}, scopes: {scopes}"
70
- )
71
- valid_uri, instance_uri = self._uri_validator(resource_url)
72
- if not valid_uri:
73
- raise ValueError(str(authentication_errors.InvalidInstanceUrl))
74
- assert instance_uri is not None # for mypy
75
-
76
- local_scopes = self._resolve_scopes_list(instance_uri, scopes)
77
- msal_auth_client = self._get_client()
78
-
79
- if isinstance(msal_auth_client, ManagedIdentityClient):
80
- logger.info("Acquiring token using Managed Identity Client.")
81
- auth_result_payload = await _async_acquire_token_for_client(
82
- msal_auth_client, resource=resource_url
83
- )
84
- elif isinstance(msal_auth_client, ConfidentialClientApplication):
85
- logger.info("Acquiring token using Confidential Client Application.")
86
- auth_result_payload = await _async_acquire_token_for_client(
87
- msal_auth_client, scopes=local_scopes
69
+ with spans.GetAccessToken(
70
+ scopes,
71
+ self._msal_configuration.AUTH_TYPE,
72
+ ):
73
+ logger.debug(
74
+ f"Requesting access token for resource: {resource_url}, scopes: {scopes}"
88
75
  )
89
- else:
90
- auth_result_payload = None
91
-
92
- res = auth_result_payload.get("access_token") if auth_result_payload else None
93
- if not res:
94
- logger.error("Failed to acquire token for resource %s", auth_result_payload)
95
- raise ValueError(
96
- authentication_errors.FailedToAcquireToken.format(
97
- str(auth_result_payload)
76
+ valid_uri, instance_uri = self._uri_validator(resource_url)
77
+ if not valid_uri:
78
+ raise ValueError(str(authentication_errors.InvalidInstanceUrl))
79
+ assert instance_uri is not None # for mypy
80
+
81
+ local_scopes = self._resolve_scopes_list(instance_uri, scopes)
82
+ msal_auth_client = self._get_client()
83
+
84
+ if isinstance(msal_auth_client, ManagedIdentityClient):
85
+ logger.info("Acquiring token using Managed Identity Client.")
86
+ auth_result_payload = await _async_acquire_token_for_client(
87
+ msal_auth_client, resource=resource_url
88
+ )
89
+ elif isinstance(msal_auth_client, ConfidentialClientApplication):
90
+ logger.info("Acquiring token using Confidential Client Application.")
91
+ auth_result_payload = await _async_acquire_token_for_client(
92
+ msal_auth_client, scopes=local_scopes
98
93
  )
94
+ else:
95
+ auth_result_payload = None
96
+
97
+ res = (
98
+ auth_result_payload.get("access_token") if auth_result_payload else None
99
99
  )
100
+ if not res:
101
+ logger.error(
102
+ "Failed to acquire token for resource %s", auth_result_payload
103
+ )
104
+ raise ValueError(
105
+ authentication_errors.FailedToAcquireToken.format(
106
+ str(auth_result_payload)
107
+ )
108
+ )
100
109
 
101
- return res
110
+ return res
102
111
 
103
112
  async def acquire_token_on_behalf_of(
104
113
  self, scopes: list[str], user_assertion: str
@@ -109,44 +118,44 @@ class MsalAuth(AccessTokenProviderBase):
109
118
  :param user_assertion: The user assertion token.
110
119
  :return: The access token as a string.
111
120
  """
112
-
113
- msal_auth_client = self._get_client()
114
- if isinstance(msal_auth_client, ManagedIdentityClient):
115
- logger.error(
116
- "Attempted on-behalf-of flow with Managed Identity authentication."
117
- )
118
- raise NotImplementedError(
119
- str(authentication_errors.OnBehalfOfFlowNotSupportedManagedIdentity)
120
- )
121
- elif isinstance(msal_auth_client, ConfidentialClientApplication):
122
- # TODO: Handling token error / acquisition failed
123
-
124
- # MSAL in Python does not support async, so we use asyncio.to_thread to run it in
125
- # a separate thread and avoid blocking the event loop
126
- token = await asyncio.to_thread(
127
- lambda: msal_auth_client.acquire_token_on_behalf_of(
128
- scopes=scopes, user_assertion=user_assertion
129
- )
130
- )
131
-
132
- if "access_token" not in token:
121
+ with spans.AcquireTokenOnBehalfOf(scopes):
122
+ msal_auth_client = self._get_client()
123
+ if isinstance(msal_auth_client, ManagedIdentityClient):
133
124
  logger.error(
134
- f"Failed to acquire token on behalf of user: {user_assertion}"
125
+ "Attempted on-behalf-of flow with Managed Identity authentication."
135
126
  )
136
- raise ValueError(
137
- authentication_errors.FailedToAcquireToken.format(str(token))
127
+ raise NotImplementedError(
128
+ str(authentication_errors.OnBehalfOfFlowNotSupportedManagedIdentity)
129
+ )
130
+ elif isinstance(msal_auth_client, ConfidentialClientApplication):
131
+ # TODO: Handling token error / acquisition failed
132
+
133
+ # MSAL in Python does not support async, so we use asyncio.to_thread to run it in
134
+ # a separate thread and avoid blocking the event loop
135
+ token = await asyncio.to_thread(
136
+ lambda: msal_auth_client.acquire_token_on_behalf_of(
137
+ scopes=scopes, user_assertion=user_assertion
138
+ )
138
139
  )
139
140
 
140
- return token["access_token"]
141
+ if "access_token" not in token:
142
+ logger.error(
143
+ f"Failed to acquire token on behalf of user: {user_assertion}"
144
+ )
145
+ raise ValueError(
146
+ authentication_errors.FailedToAcquireToken.format(str(token))
147
+ )
141
148
 
142
- logger.error(
143
- f"On-behalf-of flow is not supported with the current authentication type: {msal_auth_client.__class__.__name__}"
144
- )
145
- raise NotImplementedError(
146
- authentication_errors.OnBehalfOfFlowNotSupportedAuthType.format(
147
- msal_auth_client.__class__.__name__
149
+ return token["access_token"]
150
+
151
+ logger.error(
152
+ f"On-behalf-of flow is not supported with the current authentication type: {msal_auth_client.__class__.__name__}"
153
+ )
154
+ raise NotImplementedError(
155
+ authentication_errors.OnBehalfOfFlowNotSupportedAuthType.format(
156
+ msal_auth_client.__class__.__name__
157
+ )
148
158
  )
149
- )
150
159
 
151
160
  @staticmethod
152
161
  def _resolve_authority(
@@ -318,78 +327,80 @@ class MsalAuth(AccessTokenProviderBase):
318
327
  :return: A tuple containing the agentic instance token and the agent application token.
319
328
  :rtype: tuple[str, str]
320
329
  """
321
-
322
330
  if not agent_app_instance_id:
323
331
  raise ValueError(
324
332
  str(authentication_errors.AgentApplicationInstanceIdRequired)
325
333
  )
326
334
 
327
- logger.info(
328
- "Attempting to get agentic instance token from agent_app_instance_id %s",
329
- agent_app_instance_id,
330
- )
331
- agent_token_result = await self.get_agentic_application_token(
332
- tenant_id, agent_app_instance_id
333
- )
335
+ with spans.GetAgenticInstanceToken(agent_app_instance_id):
334
336
 
335
- if not agent_token_result:
336
- logger.error(
337
- "Failed to acquire agentic instance token or agent token for agent_app_instance_id %s",
337
+ logger.info(
338
+ "Attempting to get agentic instance token from agent_app_instance_id %s",
338
339
  agent_app_instance_id,
339
340
  )
340
- raise Exception(
341
- authentication_errors.FailedToAcquireAgenticInstanceToken.format(
342
- agent_app_instance_id
343
- )
341
+ agent_token_result = await self.get_agentic_application_token(
342
+ tenant_id, agent_app_instance_id
344
343
  )
345
344
 
346
- authority = MsalAuth._resolve_authority(self._msal_configuration, tenant_id)
345
+ if not agent_token_result:
346
+ logger.error(
347
+ "Failed to acquire agentic instance token or agent token for agent_app_instance_id %s",
348
+ agent_app_instance_id,
349
+ )
350
+ raise Exception(
351
+ authentication_errors.FailedToAcquireAgenticInstanceToken.format(
352
+ agent_app_instance_id
353
+ )
354
+ )
347
355
 
348
- instance_app = ConfidentialClientApplication(
349
- client_id=agent_app_instance_id,
350
- authority=authority,
351
- client_credential={"client_assertion": agent_token_result},
352
- # token_cache=self._token_cache,
353
- )
356
+ authority = MsalAuth._resolve_authority(self._msal_configuration, tenant_id)
354
357
 
355
- agentic_instance_token = await _async_acquire_token_for_client(
356
- instance_app, ["api://AzureAdTokenExchange/.default"]
357
- )
358
+ instance_app = ConfidentialClientApplication(
359
+ client_id=agent_app_instance_id,
360
+ authority=authority,
361
+ client_credential={"client_assertion": agent_token_result},
362
+ # token_cache=self._token_cache,
363
+ )
358
364
 
359
- if not agentic_instance_token:
360
- logger.error(
361
- "Failed to acquire agentic instance token or agent token for agent_app_instance_id %s",
362
- agent_app_instance_id,
365
+ agentic_instance_token = await _async_acquire_token_for_client(
366
+ instance_app, ["api://AzureAdTokenExchange/.default"]
363
367
  )
364
- raise Exception(
365
- authentication_errors.FailedToAcquireAgenticInstanceToken.format(
366
- agent_app_instance_id
368
+
369
+ if not agentic_instance_token:
370
+ logger.error(
371
+ "Failed to acquire agentic instance token or agent token for agent_app_instance_id %s",
372
+ agent_app_instance_id,
373
+ )
374
+ raise Exception(
375
+ authentication_errors.FailedToAcquireAgenticInstanceToken.format(
376
+ agent_app_instance_id
377
+ )
367
378
  )
368
- )
369
379
 
370
- # future scenario where we don't know the blueprint id upfront
380
+ # future scenario where we don't know the blueprint id upfront
371
381
 
372
- token = agentic_instance_token.get("access_token")
373
- if not token:
374
- logger.error(
375
- "Failed to acquire agentic instance token, %s", agentic_instance_token
376
- )
377
- raise ValueError(
378
- authentication_errors.FailedToAcquireToken.format(
379
- str(agentic_instance_token)
382
+ token = agentic_instance_token.get("access_token")
383
+ if not token:
384
+ logger.error(
385
+ "Failed to acquire agentic instance token, %s",
386
+ agentic_instance_token,
380
387
  )
381
- )
382
-
383
- logger.debug(
384
- "Agentic blueprint id: %s",
385
- _DeferredString(
386
- lambda: jwt.decode(token, options={"verify_signature": False}).get(
387
- "xms_par_app_azp"
388
+ raise ValueError(
389
+ authentication_errors.FailedToAcquireToken.format(
390
+ str(agentic_instance_token)
391
+ )
388
392
  )
389
- ),
390
- )
391
393
 
392
- return agentic_instance_token["access_token"], agent_token_result
394
+ logger.debug(
395
+ "Agentic blueprint id: %s",
396
+ _DeferredString(
397
+ lambda: jwt.decode(token, options={"verify_signature": False}).get(
398
+ "xms_par_app_azp"
399
+ )
400
+ ),
401
+ )
402
+
403
+ return agentic_instance_token["access_token"], agent_token_result
393
404
 
394
405
  async def get_agentic_user_token(
395
406
  self,
@@ -414,71 +425,73 @@ class MsalAuth(AccessTokenProviderBase):
414
425
  str(authentication_errors.AgentApplicationInstanceIdAndUserIdRequired)
415
426
  )
416
427
 
417
- logger.info(
418
- "Attempting to get agentic user token from agent_app_instance_id %s and agentic_user_id %s",
419
- agent_app_instance_id,
420
- agentic_user_id,
421
- )
422
- instance_token, agent_token = await self.get_agentic_instance_token(
423
- tenant_id, agent_app_instance_id
424
- )
428
+ with spans.GetAgenticUserToken(agent_app_instance_id, agentic_user_id, scopes):
425
429
 
426
- if not instance_token or not agent_token:
427
- logger.error(
428
- "Failed to acquire instance token or agent token for agent_app_instance_id %s and agentic_user_id %s",
430
+ logger.info(
431
+ "Attempting to get agentic user token from agent_app_instance_id %s and agentic_user_id %s",
429
432
  agent_app_instance_id,
430
433
  agentic_user_id,
431
434
  )
432
- raise Exception(
433
- authentication_errors.FailedToAcquireInstanceOrAgentToken.format(
434
- agent_app_instance_id, agentic_user_id
435
- )
435
+ instance_token, agent_token = await self.get_agentic_instance_token(
436
+ tenant_id, agent_app_instance_id
436
437
  )
437
438
 
438
- authority = MsalAuth._resolve_authority(self._msal_configuration, tenant_id)
439
-
440
- instance_app = ConfidentialClientApplication(
441
- client_id=agent_app_instance_id,
442
- authority=authority,
443
- client_credential={"client_assertion": agent_token},
444
- # token_cache=self._token_cache,
445
- )
439
+ if not instance_token or not agent_token:
440
+ logger.error(
441
+ "Failed to acquire instance token or agent token for agent_app_instance_id %s and agentic_user_id %s",
442
+ agent_app_instance_id,
443
+ agentic_user_id,
444
+ )
445
+ raise Exception(
446
+ authentication_errors.FailedToAcquireInstanceOrAgentToken.format(
447
+ agent_app_instance_id, agentic_user_id
448
+ )
449
+ )
446
450
 
447
- logger.info(
448
- "Acquiring agentic user token for agent_app_instance_id %s and agentic_user_id %s",
449
- agent_app_instance_id,
450
- agentic_user_id,
451
- )
452
- # MSAL in Python does not support async, so we use asyncio.to_thread to run it in
453
- # a separate thread and avoid blocking the event loop
454
- auth_result_payload = await _async_acquire_token_for_client(
455
- instance_app,
456
- scopes,
457
- data={
458
- "user_id": agentic_user_id,
459
- "user_federated_identity_credential": instance_token,
460
- "grant_type": "user_fic",
461
- },
462
- )
451
+ authority = MsalAuth._resolve_authority(self._msal_configuration, tenant_id)
463
452
 
464
- if not auth_result_payload:
465
- logger.error(
466
- "Failed to acquire agentic user token for agent_app_instance_id %s and agentic_user_id %s, %s",
467
- agent_app_instance_id,
468
- agentic_user_id,
469
- auth_result_payload,
453
+ instance_app = ConfidentialClientApplication(
454
+ client_id=agent_app_instance_id,
455
+ authority=authority,
456
+ client_credential={"client_assertion": agent_token},
457
+ # token_cache=self._token_cache,
470
458
  )
471
- return None
472
459
 
473
- access_token = auth_result_payload.get("access_token")
474
- if not access_token:
475
- logger.error(
476
- "Failed to acquire agentic user token for agent_app_instance_id %s and agentic_user_id %s, %s",
460
+ logger.info(
461
+ "Acquiring agentic user token for agent_app_instance_id %s and agentic_user_id %s",
477
462
  agent_app_instance_id,
478
463
  agentic_user_id,
479
- auth_result_payload,
480
464
  )
481
- return None
465
+ # MSAL in Python does not support async, so we use asyncio.to_thread to run it in
466
+ # a separate thread and avoid blocking the event loop
467
+ auth_result_payload = await _async_acquire_token_for_client(
468
+ instance_app,
469
+ scopes,
470
+ data={
471
+ "user_id": agentic_user_id,
472
+ "user_federated_identity_credential": instance_token,
473
+ "grant_type": "user_fic",
474
+ },
475
+ )
476
+
477
+ if not auth_result_payload:
478
+ logger.error(
479
+ "Failed to acquire agentic user token for agent_app_instance_id %s and agentic_user_id %s, %s",
480
+ agent_app_instance_id,
481
+ agentic_user_id,
482
+ auth_result_payload,
483
+ )
484
+ return None
485
+
486
+ access_token = auth_result_payload.get("access_token")
487
+ if not access_token:
488
+ logger.error(
489
+ "Failed to acquire agentic user token for agent_app_instance_id %s and agentic_user_id %s, %s",
490
+ agent_app_instance_id,
491
+ agentic_user_id,
492
+ auth_result_payload,
493
+ )
494
+ return None
482
495
 
483
- logger.info("Acquired agentic user token response.")
484
- return access_token
496
+ logger.info("Acquired agentic user token response.")
497
+ return access_token
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-authentication-msal
3
- Version: 0.9.0.dev6
3
+ Version: 0.9.0.dev7
4
4
  Summary: A msal-based authentication library for Microsoft Agents
5
5
  Author: Microsoft Corporation
6
6
  License-Expression: MIT
@@ -15,7 +15,7 @@ Classifier: Operating System :: OS Independent
15
15
  Requires-Python: >=3.10
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: microsoft-agents-hosting-core==0.9.0.dev6
18
+ Requires-Dist: microsoft-agents-hosting-core==0.9.0.dev7
19
19
  Requires-Dist: msal>=1.34.0
20
20
  Requires-Dist: requests>=2.32.3
21
21
  Dynamic: license-file
@@ -0,0 +1,3 @@
1
+ microsoft-agents-hosting-core==0.9.0.dev7
2
+ msal>=1.34.0
3
+ requests>=2.32.3
@@ -1 +0,0 @@
1
- 0.9.0.dev6
@@ -1,3 +0,0 @@
1
- microsoft-agents-hosting-core==0.9.0.dev6
2
- msal>=1.34.0
3
- requests>=2.32.3