如何授予python脚本对azure blob容器的有限访问权限

如何授予python脚本对azure blob容器的有限访问权限,python,azure,azure-storage-blobs,Python,Azure,Azure Storage Blobs,我希望我的python脚本能够将新blob附加到azure中的容器中。使用共享访问签名(SA)似乎是一条可行之路 但我不知道如何使用它们。我不想通过向脚本提供存储帐户密钥来授予它对azure帐户的完全访问权限,因此使用SAS并限制脚本创建和删除delete、get和list的能力似乎是可以的。 但是如何在脚本中使用令牌呢 以下是我的测试代码: #!/usr/bin/env python3 import requests from azure.storage.blob import BlockB

我希望我的python脚本能够将新blob附加到azure中的容器中。使用共享访问签名(SA)似乎是一条可行之路

但我不知道如何使用它们。我不想通过向脚本提供存储帐户密钥来授予它对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

此服务.exists()调用失败,错误为:
azure.common.AzureHttpError:服务器未能对请求进行身份验证。确保包括签名在内的授权头的值格式正确。

正如@DavidMakogon所说的,这听起来像是指。事实上,这有助于回答你的问题

根据您的描述,您似乎已经知道如何将这些方法与、with、with一起用于为不同级别(帐户、容器、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
  • 将Python脚本中的SAS与Azure Storage SDK一起使用,类的构造方法&有一个参数
    SAS_token
    ,如下所述,您可以传递
    SAS
  • sas_令牌(str)–用于验证请求而不是帐户密钥的共享访问签名令牌。如果同时指定了帐户密钥和sas令牌,则将使用帐户密钥进行签名。如果两者都未指定,则将使用匿名访问

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

    service = BlockBlobService(sas_token=sas)
    

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

    #!/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
    并正确地确定日期时间。时区是你最可怕的噩梦

    嗯。。。我只是在谷歌上搜索了“azure sas python”。第一次点击似乎回答了你的问题。只是做了同样的事情,我们只能找到过时的文档或链接,人们做的事情与我想做的略有不同。我想删除代码中的帐户密钥。应该只允许我的脚本上载新blob并更新现有blob。没有阅读,没有列表,没有删除。Thx,这很有帮助。但我还是不明白这是怎么回事。我在问题中添加了示例代码。SAS令牌仅对1个blob有效,还是可以对整个容器使用它?因为我需要提供一个blob来生成它。这对我来说似乎很奇怪。
    #!/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