我正在尝试通过Python向Azure提出请求,以列出我拥有的存储服务。

我的基本代码是这样的:

import httplib
conn = httplib.HTTPSConnection('management.core.windows.net')
conn.request('GET', '/[subscription id]/services/storageservices/')
response = conn.getresponse()
print response.status response.reason


显然,由于我未进行身份验证,因此此内容打印为403 Forbidden

因此,我按照http://msdn.microsoft.com/en-us/library/windowsazure/gg651127上的说明创建了证书,并给了我cert.cer。我将.cer上传到我的Azure帐户,并将.cer复制到我正在使用Python的Linux VM中。我将代码修改为:

import httplib
cert_file = '/path/to/cert.cer'
conn = httplib.HTTPSConnection('management.core.windows.net', cert_file = cert_file)
conn.request('GET', '/[subscription id]/services/storageservices/')


并得到错误:

ssl.SSLError: [Errno 336265225] _ssl.c:351: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib


在这种印象下,可能是因为我试图使用.cer证书而不是.pem,并且基于关于和.cer之间差异的here说(它们是相同的)扩展名不同的东西),我只是将.cer上的扩展名更改为.pem,然后再次尝试,却得到相同的错误。

如何正确向Azure进行身份验证以访问其API?这是我上载证书的方式的问题,还是我需要对证书做一些事情以使其适合呈现给服务器?在Windows上,我似乎可以将.cer安装到某种证书存储中-Linux中是否有与之等效的文件,我需要在使用它进行身份验证之前从中检索证书?感谢您的帮助=)

最佳答案

这是一些有效的Python代码,但是正如您所指出的,技巧是获取正确的PEM文件:

import httplib

conn = httplib.HTTPSConnection('management.core.windows.net', cert_file='cert.pem', key_file='key.pem')
conn.request('GET', '/%s/services/storageservices' % subscription_id, headers={'x-ms-version': '2011-02-25'})
print conn.getresponse().read()


我从https://github.com/smarx/waz-cmd获得了PEM文件,该文件是我编写的基于Ruby的命令行工具,用于与Service Management API进行交互。请注意,您需要两个片段(cert_filekey_file)。

您已经有了cert文件,尽管我认为您可能实际上需要通过诸如openssl之类的文件将其转换为PEM格式。对于密钥文件,我认为您需要导出在Windows计算机上创建的证书,然后使用openssl将私钥导出为PEM文件。

如今,您可以从Windows Azure门户下载.publishsettings文件,而不是创建自己的证书,该文件会生成并为您提供准备使用的证书。请参见http://blog.smarx.com/posts/calling-the-windows-azure-service-management-api-with-the-new-publishsettings-file。其中的证书采用PFX格式,但是正确的openssl魔术应该可以为您提供所需的两部分。我实际上解决了这个问题一次(在Mac上与curl一起使用),但是我不再拥有确切的命令了。 :-(今天晚上我可以旋转一下,写一篇关于它的博客文章。

编辑:

这是一个完整的Python程序,该程序在命令行上使用.publishsettings文件,将密钥和证书转储到当前目录中的单个文件(cert.pem)中,然后使用它来调用服务管理API并打印您所有存储帐户的名称。在运行之前,只需pip install lxml pyopenssl

import httplib
import argparse
from StringIO import StringIO
from lxml import etree
import base64
from OpenSSL.crypto import *

parser = argparse.ArgumentParser()
parser.add_argument('file', metavar='file', type=str, help='Your .publishsettings file.')
args = parser.parse_args()

tree = etree.parse(args.file)
pp = tree.find('PublishProfile')
cert = load_pkcs12(base64.decodestring(pp.get('ManagementCertificate')))
with open('cert.pem', 'w') as f:
    f.write(dump_certificate(FILETYPE_PEM, cert.get_certificate()))
    f.write(dump_privatekey(FILETYPE_PEM, cert.get_privatekey()))
subscription_id = pp.find('Subscription').get('Id')

conn = httplib.HTTPSConnection('management.core.windows.net', cert_file='cert.pem')
conn.request('GET', '/%s/services/storageservices' % subscription_id, headers={'x-ms-version': '2011-02-25'})
for e in etree.parse(StringIO(conn.getresponse().read())).iterfind('//{http://schemas.microsoft.com/windowsazure}ServiceName'): print e.text

关于python - 如何验证对Windows Azure的管理服务请求?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11977725/

10-11 06:48