Azure Blob存储触发Google Cloud Function时Webhook验证失败排查
- 需求:每次向Azure Blob Storage容器上传或更新文件时,触发Google Cloud上的Cloud Function,由该函数加载并处理Blob容器中的新文件。
- 测试代码:为验证通信是否正常,创建了简单的测试函数:
import functions_framework @functions_framework.http def hello_get(request): return "Hello World!"
- 操作:在Azure侧创建Webhook订阅Blob存储容器的变更事件,端点设置为Cloud Function的触发URL。
- 错误信息:部署事件订阅时收到错误:
Deployment has failed with the following error: {"code":"Url validation","message":"Webhook validation handshake failed for function trigger URL. Http POST request returned 2XX response with response body Hello World!. When a validation request is accepted without validation code in the response body, Http GET is expected on the validation url included in the validation event(within 10 minutes). Activity id:xxxxx, timestamp: 9/5/2023 2:55:41 PM (UTC)."}
- 疑问:想了解该错误的原因,问题出在Azure侧还是GCP侧?已设置Cloud Function的入站规则为允许所有流量,运行函数的服务账号具备所有必要的IAM调用权限。
问题出在GCP侧的Cloud Function,原因是你的函数没有正确处理Azure Event Grid的Webhook验证流程。
Azure在创建Webhook订阅时,会发送两种类型的验证请求:
- POST请求:携带验证代码在请求体中,要求服务端返回该验证代码作为响应体,以此完成验证。
- GET请求:携带验证代码在查询参数中,要求服务端返回该代码。
你的当前函数不管收到什么请求都返回"Hello World!",没有处理Azure的验证逻辑,导致验证握手失败。
修改后的Cloud Function代码需要处理这两种验证请求,示例如下:
import functions_framework import json @functions_framework.http def handle_azure_events(request): # 处理POST类型的验证请求 if request.method == 'POST': req_body = request.get_json() if req_body and 'validationCode' in req_body: return req_body['validationCode'] # 后续处理实际的Blob事件逻辑 return "Event processed" # 处理GET类型的验证请求 elif request.method == 'GET': validation_code = request.args.get('validationCode') if validation_code: return validation_code return "Invalid request", 400
部署修改后的函数后,重新创建Azure的事件订阅,就能完成验证握手了。
内容的提问来源于stack exchange,提问作者Berra

