Azure Bot Service集成Azure AD认证遇AADSTS50013签名验证失败
问题描述
开发Microsoft Teams机器人时,在基于Azure Active Directory(Azure AD)的Azure Bot Service用户认证环节持续报错:
AADSTS50013: Assertion failed signature validation. [Reason - The token issuer doesn't match the expected issuer]
机器人需通过OAuth认证从Microsoft Graph API获取用户详情,已完成的配置流程:
- 创建Azure Bot Service并配置消息接收端点,可正常接收Teams消息;
- 在Azure AD中完成应用注册,获取app id、密钥及租户信息,添加了
User.Read.All、User.Read、email、profile、openid、TeamsActivity.Read、TeamsActivity.Send等API权限; - 在Bot Service中为该Azure AD应用配置OAuth认证;
- 代码中使用的app_id和密码来自Bot Service。
核心代码如下:
# Microsoft Teams Configuration BOT_SETTINGS = BotFrameworkAdapterSettings( app_id="", app_password="" ) adapter = BotFrameworkAdapter(BOT_SETTINGS) # MSAL Configuration MSAL_CONFIG = { "authority": "https://login.microsoftonline.com/d125fb3d-2c8c-471e-a846-d135c889df59", "client_id": BOT_SETTINGS.app_id, "client_credential": BOT_SETTINGS.app_password } msal_app = ConfidentialClientApplication( client_id=MSAL_CONFIG["client_id"], client_credential=MSAL_CONFIG["client_credential"], authority=MSAL_CONFIG["authority"] ) # ThreadPool for async handling executor = ThreadPoolExecutor() @app.route('/api/messages', methods=['POST']) def messages(): """ Endpoint to handle messages from Microsoft Teams. """ try: body = request.json logging.debug(f"Received message: {body}") auth_header = request.headers.get("Authorization", "").replace("Bearer ", "") # Validate the token using MSAL token_validation_result = validate_token(auth_header) if not token_validation_result["valid"]: logging.error(f"Token validation failed: {token_validation_result['error']}") return jsonify({"error": "Unauthorized. No valid identity."}), 401 # Process the incoming message async def process_activity(activity): if activity.type == ActivityTypes.message: user_message = activity.text logging.info(f"Received Teams message: {user_message}") # Process the query asynchronously executor.submit(handle_query, user_message, activity) # Use Bot Framework Adapter to process the request activity = Activity().deserialize(body) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) response = loop.run_until_complete(adapter.process_activity(activity, auth_header, process_activity)) return jsonify({"status": "ok"}), 200 except Exception as e: logging.error(f"Error handling message: {e}") return jsonify({"error": "An error occurred"}), 500
排查方向与解决方案
- 验证Authority端点与租户匹配:检查MSAL配置中的
authority是否对应正确租户。多租户应用需使用https://login.microsoftonline.com/common,单租户需确认租户ID与Azure AD应用注册的租户ID完全一致,避免复制错误。 - 确认Bot Service与Azure AD应用关联一致性:Bot Service配置OAuth时,必须使用同一Azure AD应用的app ID和密钥,不能混用Bot Service自动创建的应用(部分场景下Bot Service会生成默认应用,需确认是否与手动注册应用一致)。
- 检查令牌颁发者与预期值匹配:解码收到的JWT令牌,查看
iss字段值,确认其与MSAL配置的authority拼接后的颁发者(如https://login.microsoftonline.com/{tenant-id}/v2.0)完全一致。注意v1.0与v2.0端点的颁发者格式差异,确保MSAL配置的端点版本与应用注册的令牌版本匹配。 - 移除重复令牌验证逻辑:Bot Framework Adapter已内置令牌验证,代码中手动调用
validate_token会导致双重验证冲突,直接依赖adapter.process_activity完成身份验证即可。 - 确认API权限授予状态:检查Azure AD应用的权限是否已完成管理员同意,尤其是
User.Read.All这类需要管理员授权的范围,未授权会导致令牌生成或验证异常。 - 核对重定向URI配置:Azure AD应用注册中的重定向URI必须与Bot Service配置的OAuth重定向URI一致(通常为
https://token.botframework.com/.auth/web/redirect),不匹配会引发令牌颁发错误。
内容的提问来源于stack exchange,提问作者Lakshman Diwaakar
相关产品推荐
相关产品推荐

