Add Support for CopilotStudio Agent-to-Agent Connector for AgentsSDK to populate UserAuthorization#232
Add Support for CopilotStudio Agent-to-Agent Connector for AgentsSDK to populate UserAuthorization#232rodrigobr-msft wants to merge 4 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This pull request adds support for connector user authorization and introduces a new MCS (Microsoft Connector Service) client implementation for handling specific user role types. The PR includes a new authorization framework with multiple authorization handlers for different authentication scenarios.
Key Changes
- Added
MCSConnectorClientfor handling connector user communications - Implemented authorization framework with support for agentic and user-based authentication flows
- Added
connector_userrole type toRoleTypesenum for distinguishing connector users
Reviewed Changes
Copilot reviewed 5 out of 14 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
rest_channel_service_client_factory.py |
Added logic to return MCSConnectorClient for connector user role types |
mcs_connector_client.py |
New client implementation for MCS operations with conversation and attachment operations |
authorization.py |
Core authorization class managing sign-in flows, token caching, and handler lifecycle |
auth_handler.py |
Configuration class for OAuth providers with connection and scope settings |
_sign_in_state.py |
Storage item for maintaining sign-in state across turns |
_sign_in_response.py |
Response wrapper for sign-in attempts with flow state tracking |
agentic_user_authorization.py |
Authorization handler for agentic user tokens |
_user_authorization.py |
Authorization handler for standard OAuth flows with token exchange |
_connector_user_authorization.py |
Incomplete authorization handler for connector users |
_authorization_handler.py |
Abstract base class for authorization handlers |
role_types.py |
Added connector_user role type |
__init__.py files |
Updated exports for new authorization classes |
Comments suppressed due to low confidence (2)
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/auth/_handlers/_connector_user_authorization.py:67
- Syntax Error (in Python 3).
try:
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/connector/client/mcs_connector_client.py:9
- Import of 'BytesIO' is not used.
from io import BytesIO
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| """ | ||
| Copyright (c) Microsoft Corporation. All rights reserved. | ||
| Licensed under the MIT License. | ||
| """ | ||
|
|
||
| from abc import ABC | ||
| from typing import Optional | ||
| import logging | ||
|
|
||
| from microsoft_agents.activity import TokenResponse | ||
|
|
||
| from ....turn_context import TurnContext | ||
| from ....storage import Storage | ||
| from ....authorization import Connections | ||
| from ...._oauth import _FlowStateTag | ||
| from ..auth_handler import AuthHandler | ||
| from .._sign_in_response import _SignInResponse | ||
|
|
||
| from ._authorization_handler import _AuthorizationHandler |
There was a problem hiding this comment.
Missing imports: ClaimsIdentity is referenced on line 71 but not imported. The file imports ABC but it's not used since _AuthorizationHandler is already an ABC.
| ) -> TokenResponse: | ||
|
|
||
| token_response = self.create_token_response(context) | ||
|
|
There was a problem hiding this comment.
Incomplete implementation: The get_refreshed_token method is missing a return statement. It should return the token_response created on line 55.
| return token_response |
| def create_token_response(self, context: TurnContext) -> TokenResponse: | ||
|
|
||
| if _ConnectorUserAuthorizationHandler._is_case_sensitive_claims_identity( | ||
| context.turn_state.get("claims_identity") | ||
| ): | ||
| token_response = TokenResponse(token=identity.security_token.unsafe_to_str()) | ||
|
|
||
| try: | ||
| jwt_token = |
There was a problem hiding this comment.
Incomplete implementation: The create_token_response method is incomplete. Lines 67-68 appear to be unfinished code with an incomplete variable assignment (jwt_token = ). This code will not compile.
| Licensed under the MIT License. | ||
| """ | ||
|
|
||
| from abc import ABC |
There was a problem hiding this comment.
Unused import: ABC is imported on line 6 but never used, since _AuthorizationHandler is already an abstract base class.
| from abc import ABC |
| from microsoft_agents.activity import ( | ||
| Activity, | ||
| ChannelAccount, | ||
| ConversationParameters, | ||
| ConversationResourceResponse, | ||
| ResourceResponse, | ||
| ConversationsResult, | ||
| PagedMembersResult, | ||
| ) | ||
| from microsoft_agents.hosting.core.connector import ConnectorClientBase | ||
| from ..attachments_base import AttachmentsBase | ||
| from ..conversations_base import ConversationsBase | ||
| from .connector_client import AttachmentsOperations | ||
| from ..get_product_info import get_product_info |
There was a problem hiding this comment.
Missing imports: Transcript and AttachmentData are used in method signatures (lines 56 and 62) but are not imported.
| # def get_obo_settings(self) -> dict: | ||
| # """Get On-Behalf-Of settings for the auth handler. | ||
|
|
||
| # :return: The OBO settings dictionary. | ||
| # :rtype: dict | ||
| # """ | ||
| # return self._ |
There was a problem hiding this comment.
This comment appears to contain commented-out code.
| # def get_obo_settings(self) -> dict: | |
| # """Get On-Behalf-Of settings for the auth handler. | |
| # :return: The OBO settings dictionary. | |
| # :rtype: dict | |
| # """ | |
| # return self._ |
| data = await response.json() | ||
| return ResourceResponse.model_validate(data) | ||
|
|
||
| async def reply_to_activity(self, conversation_id: str, body: Activity) -> ResourceResponse: |
There was a problem hiding this comment.
This method requires 3 positional arguments, whereas overridden ConversationsBase.reply_to_activity requires 4.
| async def reply_to_activity(self, conversation_id: str, body: Activity) -> ResourceResponse: | |
| async def reply_to_activity(self, conversation_id: str, activity_id: str, body: Activity) -> ResourceResponse: | |
| # The activity_id argument is accepted for signature compatibility, but not used in this implementation. |
| """Connector Client for Microsoft Agents.""" | ||
|
|
||
| import logging | ||
| from typing import Any, Optional |
There was a problem hiding this comment.
Import of 'Any' is not used.
| from typing import Any, Optional | |
| from typing import Optional |
| PagedMembersResult, | ||
| ) | ||
| from microsoft_agents.hosting.core.connector import ConnectorClientBase | ||
| from ..attachments_base import AttachmentsBase |
There was a problem hiding this comment.
Import of 'AttachmentsBase' is not used.
| from ..attachments_base import AttachmentsBase |
| from microsoft_agents.hosting.core.connector import ConnectorClientBase | ||
| from ..attachments_base import AttachmentsBase | ||
| from ..conversations_base import ConversationsBase | ||
| from .connector_client import AttachmentsOperations |
There was a problem hiding this comment.
Import of 'AttachmentsOperations' is not used.
| from .connector_client import AttachmentsOperations |
This pull request introduces support for the new "connector user" role type and adds a new client implementation for handling connector user scenarios in the Microsoft Agents framework. The main changes include extending the role types, adding a new authorization handler, implementing the
MCSConnectorClient, and updating the client factory logic to use the new client when appropriate.Connector user role support:
connector_userto theRoleTypesenum inrole_types.py, enabling identification of connector users in activities.Connector user client implementation:
MCSConnectorClientand supporting classes inmcs_connector_client.py, providing a specialized connector client for connector user flows, including conversation-related operations and error handling.__init__.pyto exportMCSConnectorClient, making it available for import throughout the codebase.Authorization flow for connector users:
_ConnectorUserAuthorizationHandlerin_connector_user_authorization.pyto manage OAuth authorization for connector users, including sign-in and token refresh logic.Client factory logic:
create_connector_clientinrest_channel_service_client_factory.pyto return anMCSConnectorClientwhen the recipient role isconnector_user, ensuring the correct client is used for connector user scenarios.