如何校验发送至bot的请求是否真实来源于Teams平台
Teams 机器人校验请求真实来源的实现方案
所有从Teams平台经Azure Bot Service转发到你机器人端点的请求,都会携带标准化的身份签名字段,严格执行以下校验逻辑,就能完全拦截第三方构造的伪造cURL请求:
核心校验逻辑:JWT 签名验签(必做,是防伪造的核心)
Teams 发出的每一条请求都会在请求头携带 Authorization: Bearer <JWT令牌> 字段,你必须对这个令牌做全维度校验,任何一项不通过直接返回403拒绝即可:
- 校验令牌格式:没有带合法Bearer前缀的请求直接拦截,普通伪造请求通常不会携带这个头
- 校验签发方:JWT载荷里的
iss字段必须为https://api.botframework.com,非官方签发的令牌直接拦截 - 校验受众:JWT载荷里的
aud字段必须和你在Azure Bot注册时拿到的专属Bot App ID完全一致,避免其他合法Bot的令牌被拿来伪造请求到你的服务 - 校验有效期:核对
exp(过期时间)、nbf(生效时间)字段,过期、未生效的令牌直接拦截 - 校验数字签名:JWT是用RS256非对称算法签名的,你可以通过Azure Bot Service公开的元数据接口拿到对应
kid的公钥,对令牌签名做验签,确认令牌内容未被篡改、确实是官方服务签发。这一步是核心,没有官方私钥的第三方根本伪造不出能通过验签的令牌。
辅助加固校验(可选,能进一步降低被攻击的概率)
- 专属请求头校验:合法Teams请求会携带
x-ms-bot-agent、x-ms-teams-message-type等专属头,缺少这些头的请求可以直接拦截(注意这步不能单独用,因为cURL可以随便构造请求头,必须配合上面的JWT验签) - IP白名单限制:你可以在服务端防火墙、网关层配置入站规则,只允许Azure Bot Service官方公布的出口IP段访问你的机器人消息接收端点,从网络层直接拦截陌生来源的请求。
校验逻辑伪代码参考
def verify_teams_request(request, your_bot_app_id): # 提取Authorization头 auth_header = request.headers.get("Authorization", "") if not auth_header.startswith("Bearer "): return False token = auth_header[7:] try: # 先解析JWT头部拿公钥ID unverified_header = jwt.get_unverified_header(token) # 从官方公开元数据拉取对应kid的公钥 public_key = get_bot_public_key(unverified_header["kid"]) # 全参数校验JWT jwt.decode( token, key=public_key, audience=your_bot_app_id, issuer="https://api.botframework.com", algorithms=["RS256"], options={"verify_exp": True, "verify_nbf": True} ) return True except (jwt.InvalidTokenError, KeyError): # 任何校验不通过都判定为非法请求 return False
注意:不要只靠判断请求体里有没有Teams相关字段、有没有特定请求头就判定请求合法,这些内容攻击者用cURL可以完全伪造,只有通过非对称签名验签的JWT校验,才能100%确认请求来源是官方Teams平台。
内容的提问来源于stack exchange,提问作者TFesmire
相关产品推荐
相关产品推荐

