我正在尝试通过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_file
和key_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/