“订阅验证请求失败。响应必须与validationToken查询参数完全匹配。”

时间:2020-07-24 20:59:11

标签: microsoft-graph-api

我需要为OneDrive(我/驱动器/ SharedWithMe)启用更改通知订阅,但发布有效负载时却出现错误。

当我将资源更改为Microsoft API建议订阅的OneDrive(me / drive / root)时,也会出现错误。

我为应用设置了API权限。很少有需要管理员同意的应用程序许可,但当前用户无法完成。用户授予如下。

我已经创建了ngrok URL来重定向Web服务器http:// localhost:5000 / notify到ngrok URL。有效负载中提到了这一点,用于发布新订阅。 Python代码也在下面给出。

我想知道启用订阅的先决条件。请提供有关许可证要求,API许可和范围,资源组以及天蓝色密钥库的信息。此要求适用于OneDrive存储订阅。

引用的文档: https://docs.microsoft.com/en-us/samples/microsoftgraph/aspnetcore-webhook-with-resource-data/sample-application---microsoft-graph-change-notifications/

当我们为新订阅发布有效负载时,它给出了错误。

有效载荷: { “ changeType”:“已更新”, “ notificationUrl”:“ https://d76209350b89.ngrok.io/notify”, “资源”:“我/驱动器/根”, “ expirationDateTime”:“ 2020-07-24T18:23:45.9356913Z”, “ clientState”:“ secretClientValue”, “ latestSupportedTlsVersion”:“ v1_2” }

订阅: https://graph.microsoft.com/v1.0/subscriptions

{
    "error": {
        "code": "InvalidRequest",
        "message": "Subscription validation request failed. Response must exactly match validationToken query parameter.",
        "innerError": {
            "date": "2020-07-22T16:45:41",
            "request-id": "d5d7f05b-9f3d-44a9-a74a-9f21e3c8a9ba"
        }
    }
}

接收验证请求的端点

    enter code here:
    http_header={'Authorization':f'Bearer 
    {token_response["accessToken"]}','Content-type':'application/json'}
    print(http_header)
    post_data={
    "changeType": "updated",
    "notificationUrl": REDIRECT_URI_2,
    "resource": "me/drive/root",
    "expirationDateTime": "2020-07-22T18:23:45.9356913Z",
    "clientState": "secretClientValue",
    "latestSupportedTlsVersion": "v1_2"
    }
res=requests.post('https://graph.microsoft.com/v1.0/subscriptions',headers=http_header,data=post_data)

接收更改通知

@app.route("/notify",methods=['GET','POST'])
    def onedrive():
    valtoken=flask.request.args.get('validationToken')
    valtok=valtoken.replace(':','%3a')
    valt=valtok.replace(' ','+')
    subscribe_url = f'https://062dece903f6.ngrok.io/notify?validationToken={valt}  HTTP/1.1'
    resp = flask.Response(status=200)
    resp.headers['content-type']="plain/text"
    resp.headers['token']=valt
    resp.headers['location'] = subscribe_url
    return resp

我正在用Python开发。任何人都已完成此操作,请分享。

谢谢。

3 个答案:

答案 0 :(得分:0)

内容类型应为text/plain。验证令牌值应作为响应正文而不是标头返回。不需要位置标头。

另外:我不确定为什么要替换字符,但是您应该简单地对URL进行解码并按原样返回。

答案 1 :(得分:0)

@app.route("/notify",methods=['POST'])
def onedrive():
    valtoken=flask.request.args.get('validationToken')
    data={"validationToken":valtoken}
    resp=app.response_class(response=json.dumps(data),status=200,mimetype='plain/text')
    return resp

答案 2 :(得分:0)

valtoken=request.args.get('validationToken')
resp=app.response_class(valtoken,status=200,content_type="text/plain")
return resp