如何给python脚本限制访问azure blob容器

时间:2017-03-28 13:59:14

标签: python azure azure-storage-blobs

我希望我的python脚本能够在azure中将新blob附加到我的容器中。使用共享访问签名(SAS)似乎是要走的路。

但我无法弄清楚如何使用它们。我不想让脚本完全访问azure帐户,方法是给它存储帐户密钥,这样使用SAS并限制脚本的功能来创建和删除delete,get和list似乎没问题。 但是如何在脚本中使用令牌?

这是我的测试代码:

#!/usr/bin/env python3

import requests
from azure.storage.blob import BlockBlobService, ContainerPermissions, ContentSettings

# this is only for testing, account key will be removed later

account_name = 'myaccountname'
account_key = 'myaccountkey'
container_name = 'mycontainer'
existing_file = 'existing_file.jpg'
new_file = 'test.jpg'

service = BlockBlobService(
    account_name=account_name,
    account_key=account_key
)
# There are two ways to create a permission
# 1. Assign boolean values to `read`/`add`/`create`/`write`/`delete` operation
# permission = BlobPermissions(read=True, add=True, create=True, write=True, delete=True)
# 2. Just simply assign a string to `_str`(A string representing the permissions) like `racwd` which means assign True to all operation
permission = ContainerPermissions(write=True)
sas = service.generate_container_shared_access_signature(
    container_name=container_name,
    permission=permission,
    protocol='https'
)
print(sas)

# Here begins the real script

service = BlockBlobService(
    account_name=account_name,
    sas_token=sas
)

assert service.exists(container_name=container_name, blob_name=existing_file)

service.create_blob_from_path(
        container_name=container_name,
        blob_name=new_file,
        file_path='./%s' % new_file,
        content_settings=ContentSettings(content_type=mimetypes.guess_type('./%s' % new_file)[0]),
        validate_content=True
)

r = requests.head('https://%s.blob.core.windows.net/%s/%s' % (account_name, container_name, new_file), timeout=2)
assert r.status_code == 200

这使service.exists()调用失败:azure.common.AzureHttpError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

2 个答案:

答案 0 :(得分:3)

正如@DavidMakogon所说,这听起来像是指blog。实际上,这对你的问题有帮助。

根据您的描述,您似乎已经知道如何将这些方法generate_account_shared_access_signatureAccountPermissiongenerate_container_shared_access_signatureContainerPermissiongenerate_blob_shared_access_signature一起使用{ {3}}为不同级别(帐户,容器,blob)生成SAS,如下面的blob级别代码。

from azure.storage.blob import BlockBlobService, BlobPermissions

account_name = '<your storage account name>'
account_key = '<your storage account key>'
container_name = 'mycontainer'

service = BlockBlobService(account_name=account_name, account_key=account_key)
# There are two ways to create a permission
# 1. Assign boolean values to `read`/`add`/`create`/`write`/`delete` operation
# permission = BlobPermissions(read=True, add=True, create=True, write=True, delete=True)
# 2. Just simply assign a string to `_str`(A string representing the permissions) like `racwd` which means assign True to all operation
permission = BlobPermissions(_str="racwd")
sas = service.generate_blob_shared_access_signature(container_name, 'test.jpg', permission)
print sas

使用SAS以Python脚本访问Azure Blob存储,如下所示。

  1. 使用SAS调用Blob Storgae REST API,您可以参考文档BlobPermission将SAS作为查询参数附加到blob url以执行相关操作,如下所示。
  2. GET https://myaccount.blob.core.windows.net/pictures/profile.jpg?sv=2012-02-12&st=2009-02-09&se=2009-02-10&sr=c&sp=r&si=YWJjZGVmZw%3d%3d&sig=dD80ihBh5jfNpymO5Hg1IdiJIEvHcJpCMiCMnN%2fRnbI%3d   
    HTTP/1.1  
    Host: myaccount.blob.core.windows.net  
    x-ms-date: <date>
    
    1. 在Python脚本中使用SAS与Azure Storage SDK,类Service SAS Examples&amp;的构造方法。 BlockBlobService有一个参数sas_token,如下所示,您可以传递sas值。
    2.   

      sas_token (str) - 用于对请求进行身份验证而不是帐户密钥的共享访问签名令牌。如果同时指定了帐户密钥和sas令牌,则将使用帐户密钥进行签名。如果两者都未指定,则将使用匿名访问。

      例如,BlockBlobService使用SAS的代码如下所示。

      service = BlockBlobService(sas_token=sas)
      

答案 1 :(得分:0)

我解决了。对于任何感兴趣的人,这是工作脚本:

#!/usr/bin/env python3

import mimetypes
mimetypes.init()
from datetime import datetime, timedelta

import requests
from azure.storage.blob import BlockBlobService, ContainerPermissions, ContentSettings

account_name = 'myaccount'
account_key = 'mykey'
container_name = 'mycontainer'
new_file = 'new_pic.jpg'
existing_file = 'old_pic.jpg'

service = BlockBlobService(account_name=account_name, account_key=account_key)
permission = ContainerPermissions(read=True, write=True)
sas = service.generate_container_shared_access_signature(container_name=container_name, permission=permission,
        protocol='https', start=datetime.now(), expiry=datetime.now() + timedelta(days=1))
print(sas)

service = BlockBlobService(account_name=account_name, sas_token=sas)

assert service.exists(container_name=container_name, blob_name=existing_file)

service.create_blob_from_path(
        container_name=container_name,
        blob_name=new_file,
        file_path=new_file,
        content_settings=ContentSettings(content_type=mimetypes.guess_type(new_file)[0]),
        validate_content=True
)

r = requests.head('https://%s.blob.core.windows.net/%s/%s' % (account_name, container_name, new_file), timeout=2)
assert r.status_code == 200

重要的是使用ContainerPermissions并使日期时间正确。时区是你最糟糕的噩梦!