在Python Flask中验证来自Microsoft Team bot的HMAC

在Python Flask中验证来自Microsoft Team bot的HMAC,python,flask,hmac,microsoft-teams,Python,Flask,Hmac,Microsoft Teams,我正在尝试使用Flask构建一个Microsoft团队聊天机器人,请按照上的说明进行操作。然而,我无法验证HMAC认证,这是我真正想要的安全性 根据指南和文档,我发现我正在使用以下Minimal测试应用程序,试图为传入请求计算HMAC。(机器人名称和说明DevBot以及下面用于测试的密钥/安全令牌) 有什么想法或建议吗?我一直在尝试各种各样的编码方法,但我有一种感觉,Flask可能在做一些修改请求主体的事情 编辑1:小澄清 编辑2:完整烧瓶应用程序示例 编辑3:示例bot详细信息、输入和输出示例

我正在尝试使用Flask构建一个Microsoft团队聊天机器人,请按照上的说明进行操作。然而,我无法验证HMAC认证,这是我真正想要的安全性

根据指南和文档,我发现我正在使用以下Minimal测试应用程序,试图为传入请求计算HMAC。(机器人名称和说明
DevBot
以及下面用于测试的密钥/安全令牌)

有什么想法或建议吗?我一直在尝试各种各样的编码方法,但我有一种感觉,Flask可能在做一些修改请求主体的事情

编辑1:小澄清

编辑2:完整烧瓶应用程序示例


编辑3:示例bot详细信息、输入和输出示例

另一个不直接与Microsoft团队交互的选项可能是使用Microsoft bot Connector API


我有一个与微软团队合作的机器人,它正在验证微软发送的JWT。

经过多次尝试和错误,并试图重现微软的C代码示例,我自己设法解决了这个问题。以下是解决方案:

#!/usr/bin/python
# coding=utf-8

from flask import Flask, request, jsonify
import hmac, hashlib, base64, json

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def webhook():
    if request.method == 'POST':


        # Reply
        data = request.get_json()
        channel = data['channelId']
        message_type = data['type']
        sender = data['from']['name']
        message_format = data['textFormat']
        message = data['text']

        # Authenticate

        security_token = b"O5XHU8OSzwx8w9YiM0URkR/Ij4TZZiZUwz7Swc+1hZE="
        request_data = request.get_data()
        digest = hmac.new(base64.b64decode(security_token), msg=request_data, digestmod=hashlib.sha256).digest()
        signature = base64.b64encode(digest).decode()

        # TODO: verify that HMAC header == signature

        return jsonify({
            'type' : 'message',
            'text' : "auth header: {0} <br>hmac: {1}".format(request.headers.get('Authorization').split(' ')[1], signature),
        })

    elif request.method == 'GET':
        return "Hello World"


if __name__ == '__main__':
    app.run(debug=True)
#/usr/bin/python
#编码=utf-8
从烧瓶导入烧瓶,请求,jsonify
导入hmac、hashlib、base64、json
app=烧瓶(名称)
@app.route('/',方法=['GET','POST'])
def webhook():
如果request.method==“POST”:
#答复:
data=request.get_json()
通道=数据['channelId']
消息类型=数据['type']
发件人=数据['from']['name']
消息格式=数据['textFormat']
消息=数据['text']
#鉴定
安全令牌=b“O5XHU8OSzwx8w9YiM0URkR/IJ4TZIZUWZ7SWC+1hZE=”
request\u data=request.get\u data()
digest=hmac.new(base64.b64解码(安全令牌),msg=request\u数据,digestmod=hashlib.sha256)。digest()
signature=base64.b64编码(摘要).decode()
#TODO:验证HMAC头==签名
返回jsonify({
“类型”:“消息”,
'text':“auth header:{0}
hmac:{1}”.format(request.headers.get('Authorization').split('')[1],签名), }) elif request.method==“GET”: 返回“你好,世界” 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': app.run(debug=True)
谢谢你的提示,马修!我会研究它,看看它是否适用于我的用例这对我不起作用,签名永远不会匹配我从团队频道获得的HMAC。好的,我认为上面的代码实际上应该是
HMAC.new(base64.b64decode(security\u token),…
这对我来说是有效的。按照上面GiacomoLacava的建议进行了更新,不再自己使用代码,因此我无法验证
Auth header: HMAC LuDmz97y/Z2KWLIZ1WZASz3HlOEtDCwk5/lL/fK8GqM= 
Calculated HMAC: eaxTdJSLuU3Z4l94bxFiWvsBhjNG9SPxwq/UHeR7KcA= 
#!/usr/bin/python
# coding=utf-8

from flask import Flask, request, jsonify
import hmac, hashlib, base64, json

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def webhook():
    if request.method == 'POST':


        # Reply
        data = request.get_json()
        channel = data['channelId']
        message_type = data['type']
        sender = data['from']['name']
        message_format = data['textFormat']
        message = data['text']

        # Authenticate

        security_token = b"O5XHU8OSzwx8w9YiM0URkR/Ij4TZZiZUwz7Swc+1hZE="
        request_data = request.get_data()
        digest = hmac.new(base64.b64decode(security_token), msg=request_data, digestmod=hashlib.sha256).digest()
        signature = base64.b64encode(digest).decode()

        # TODO: verify that HMAC header == signature

        return jsonify({
            'type' : 'message',
            'text' : "auth header: {0} <br>hmac: {1}".format(request.headers.get('Authorization').split(' ')[1], signature),
        })

    elif request.method == 'GET':
        return "Hello World"


if __name__ == '__main__':
    app.run(debug=True)