MS Teams通知类Bot获取JWT令牌遇授权失败求助
解决MS Teams通知Bot无需对话即可获取有效令牌的授权问题
你的场景是开发仅发送通知、不处理用户对话的Teams Bot,不需要依赖用户消息触发带来的临时令牌,正确方案是让Bot通过Azure AD客户端凭据流获取应用级访问令牌,直接调用Bot Connector API发送通知。以下是具体步骤:
1. 完成Bot的Azure AD应用注册配置
- 在Azure Portal的Bot应用注册中,生成并保存客户端密码(或配置证书)
- 添加API权限:选择
Bot Framework,添加应用权限类型的ChannelMessage.Send,并完成管理员同意
2. 通过客户端凭据流获取令牌
直接向Azure AD令牌端点请求应用级令牌,有效期1小时,到期后重新请求即可。示例Python代码:
import requests def get_bot_access_token(client_id, client_secret, tenant_id="common"): token_endpoint = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token" request_payload = { "grant_type": "client_credentials", "client_id": client_id, "client_secret": client_secret, "scope": "https://api.botframework.com/.default" } response = requests.post(token_endpoint, data=request_payload) response.raise_for_status() return response.json()["access_token"]
3. 使用令牌直接发送通知消息
拿到令牌后,无需触发Bot的on_turn逻辑,直接调用Bot Connector API向指定对话发送消息:
import requests def send_teams_notification(service_url, conversation_id, bot_token, content): request_headers = { "Authorization": f"Bearer {bot_token}", "Content-Type": "application/json" } message_payload = { "type": "message", "conversation": {"id": conversation_id}, "text": content, "from": {"id": "<你的Bot应用ID>"} # 替换为Bot的Azure AD应用ID } send_endpoint = f"{service_url}/v3/conversations/{conversation_id}/activities" response = requests.post(send_endpoint, json=message_payload, headers=request_headers) response.raise_for_status() return response.json()
4. 排查之前的Unauthorized错误
你之前按官方文档操作失败的常见原因:
- 权限配置错误:未添加应用权限的
ChannelMessage.Send,或未完成管理员同意 - 请求Scope错误:必须使用
https://api.botframework.com/.default,不能使用委托权限的scope - 客户端凭据无效:Azure Portal中的客户端密码过期、或证书配置错误
- 多租户Bot租户ID错误:多租户场景下租户ID需填
common,而非具体租户ID
内容的提问来源于stack exchange,提问作者klek_sik
相关产品推荐
相关产品推荐

