获取向Teams机器人发消息用户的UPN或AAD对象ID
获取机器人用户AAD Object ID的解决方案
问题根源
你遇到的情况是因为不同渠道对用户身份信息的暴露程度不同:dev.botframework.com的Web Chat测试工具直接通过AAD完成用户认证,会自动携带aadObjectId;但其他渠道(如Teams、Slack等)的Channel Account对象本身不会默认包含用户的AAD身份信息,导致你之前的代码只能拿到机器人/频道自身的ID。
可行解决办法
1. 使用OAuthPrompt获取令牌,调用Graph API获取Object ID
这是通用方案,适用于所有支持OAuth的渠道:
- 先在Azure Portal的机器人资源中配置OAuth连接设置,选择Azure Active Directory作为身份提供商,至少开启
User.Read权限。 - 在机器人中添加OAuthPrompt引导用户完成认证,再用令牌调用Graph API获取信息:
from botbuilder.dialogs import OAuthPrompt, DialogSet, DialogTurnStatus from botbuilder.core import MessageFactory import requests async def on_message_activity(self, turn_context): dialog_context = await self.dialogs.create_context(turn_context) results = await dialog_context.continue_dialog() if results.status == DialogTurnStatus.Empty: await dialog_context.begin_dialog("OAuthPrompt") elif results.status == DialogTurnStatus.Complete: token_response = results.result if token_response: # 调用Graph API /me端点获取用户AAD信息 headers = {'Authorization': f'Bearer {token_response.token}'} response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers) user_data = response.json() aad_object_id = user_data.get('id') await turn_context.send_activity(f"你的AAD Object ID是:{aad_object_id}") # 初始化时注册OAuthPrompt self.dialogs = DialogSet(self.conversation_state.create_property("DialogState")) self.dialogs.add(OAuthPrompt( "OAuthPrompt", OAuthPromptSettings( connection_name="你的Azure AD连接名称", title="登录以获取身份信息", text="请点击按钮登录", timeout=300000 ) ))
2. 针对Teams渠道的特殊方案
如果机器人仅在Teams中运行,可直接解析Teams用户ID获取AAD Object ID:
from botbuilder.core import TurnContext from botbuilder.schema import TeamsChannelAccount async def get_teams_user_aad_id(turn_context: TurnContext): if turn_context.activity.channel_id == "msteams": teams_user = turn_context.activity.from_property_as(TeamsChannelAccount) # Teams用户ID格式为29:xxxxxx,冒号后部分即为AAD Object ID if teams_user.user_id.startswith("29:"): return teams_user.user_id.split(":")[1] return None
3. 检查机器人身份验证配置
确保Azure Portal中机器人的身份验证配置正确:
- 进入机器人资源的身份验证页面,添加Azure Active Directory作为身份提供商。
- 确认已添加
User.Read等必要的Graph API权限,并完成管理员同意(如需)。
为什么之前的代码无效
你尝试的user_data.aadObjectId仅在渠道主动提供该字段时存在,只有Web Chat这类直接通过AAD认证的渠道会自动填充,其他渠道的Channel Account对象不包含该信息,因此无法直接获取。
内容的提问来源于stack exchange,提问作者Copy Run Start
相关产品推荐
相关产品推荐

