【发布时间】:2017-11-06 11:45:22
【问题描述】:
我正在尝试使用 Duo 的 python 客户端 (https://github.com/duosecurity/duo_client_python),我相信我只是用我的新手 python 眼睛错过了一些东西。我不知何故需要使用 HMAC 签名验证我对 API 的请求——我以前没有使用过,但生成起来似乎很简单(它们甚至提供了一个 python 函数)。文档在这里https://duo.com/docs/adminapi#authentication
在将我的请求传递给 API 之前,我不知道如何制作此签名以进行身份验证。来自https://duo.com/docs/adminapi#authentication:
API 使用 HTTP 基本身份验证来验证请求。使用 >Duo 应用程序的集成密钥作为 HTTP 用户名。
生成 HTTP 密码作为请求的 HMAC 签名。这将>对于每个请求都不同,并且每次都必须重新生成。
然后,它会查看添加了哪些参数以及正确生成 HMAC 签名所必需的参数。我理解这部分。我的问题是如何以及何时传递我生成的 HMAC 签名。由于 Duo 文档没有具体涉及,我认为这是我应该已经知道的 [如果我不是这样的 python 新手]。
例如,简单的身份验证调用可以正常工作(因为它们不需要身份验证):
root@box:~# python -m duo_client.client --ikey XXXXXXXX --skey XXXXXXXX --host XXXXXXXX.duosecurity.com --method GET --path /auth/v2/check 200 OK
{
“回复”:
{“时间”:1496437236}
,
“统计”:“好的”
}
但是,使用 admin 的调用需要身份验证,因此会失败:
root@box:~# python -m duo_client.client --ikey XXXXXXXX --skey XXXXXXXX --host XXXXXXXX.duosecurity.com --method GET --path /admin/v1/users signature=XXXXXXXX
401未经授权
{
“代码”:40103,
"message": "请求凭据中的无效签名",
“统计”:“失败”
}
提前感谢您的任何见解!
==编辑==
所以我想我会发布 Duo 提供的用于创建签名的函数,这看起来类似于 StackOverflow 问题中发生的事情,我发现我认为可能会有所帮助 (Python, HTTPS GET with basic authentication)。来自https://duo.com/docs/adminapi#authentication:
def 符号(方法、主机、路径、参数、skey、ikey): """ 返回 HTTP 基本身份验证(“授权”和“日期”)标头。 方法、主机、路径:来自请求的字符串 params:请求参数的字典 skey:密钥 ikey:集成密钥 """ # 创建规范字符串 现在 = email.Utils.formatdate() canon = [现在,method.upper(),host.lower(),路径] 参数 = [] 对于排序的键(params.keys()): val = 参数 [键] 如果是实例(val,unicode): val = val.encode("utf-8") args.append( '%s=%s' % (urllib.quote(key, '~'), urllib.quote(val, '~'))) canon.append('&'.join(args)) 佳能 = '\n'.join(佳能) # 签署规范字符串 sig = hmac.new(skey, canon, hashlib.sha1) auth = '%s:%s' % (ikey, sig.hexdigest()) # 返回标题 return {'Date': now, 'Authorization': 'Basic %s' % base64.b64encode(auth)}我在一个简单的脚本中使用了上述函数来打印出(以便我可以可视化)应该在我将创建的脚本中传递的内容以满足我们的需求——我将函数添加到脚本中并通过添加以下内容使用打印:
# 打印签名标题 ### 测试 ### 打印符号('GET', 'XXXhostXXX', '/admin/v1/users', 'XXXparamXXX', 'XXXskeyXXX', 'XXXXikeyXXXX')但是,我收到了这个错误:
root@box:~# ./duo.py 回溯(最近一次通话最后): 文件“./duo.py”,第 39 行,在 打印符号('GET', 'XXXhostXXX', '/admin/v1/users', 'XXXparamXXX', 'XXXskeyXXX', 'XXXikeyXXX') 文件“./duo.py”,第 18 行,符号 对于排序的键(params.keys()): AttributeError:“str”对象没有属性“keys”我只是在这里遗漏了什么吗?我一直在寻找可能导致该错误的原因,但我想我也会在这里问。
【问题讨论】:
-
发现了一些对我有帮助的东西——也就是这里的第二个答案:stackoverflow.com/questions/6999565/…