简体   繁体   English

使用 Python 的 Azure 服务主体和 storage.blob

[英]Azure service principal and storage.blob with Python

I'm trying to authenticate with a service principal through python and then accessing azure.storage.blob我正在尝试通过 python 对服务主体进行身份验证,然后访问 azure.storage.blob

Used to do it with:曾经这样做:

NAME = '****'
KEY = '****'
block_blob_service = BlockBlobService(account_name=NAME, account_key=KEY, protocol='https')

But I cant make it work with the service principal:但我不能让它与服务主体一起工作:

TENANT_ID = '****'

CLIENT = '****'

KEY_SERVICE = '****'

credentials = ServicePrincipalCredentials(
    client_id = CLIENT,
    secret = KEY_SERVICE,
    tenant = TENANT_ID
    )

I'm a little confused how I pair those 2 and whatever I try it just gives me a timeout when I'm trying to upload a blob.我有点困惑我是如何将这两个配对的,无论我尝试什么,当我尝试上传 blob 时,它都会给我一个超时。

I don't think Azure Storage Service supports service principal credentials.我认为 Azure 存储服务不支持服务主体凭据。 Actually it only accepts two kinds of credentials currently: shared keys and Shared Access Signature (SAS).实际上它目前只接受两种凭证:共享密钥和共享访问签名(SAS)。

Azure Storage works specifically with account name + key (whether primary or secondary). Azure 存储专门用于帐户名 + 密钥(无论是主要的还是次要的)。 There is no notion of service principal / AD-based access.没有服务主体/基于 AD 的访问的概念。

Your first example (setting up the blob service endpoint) with account name + key is the correct way to operate.您的第一个示例(设置 blob 服务端点)使用帐户名 + 密钥是正确的操作方式。

Note: As Zhaoxing mentioned, you can also use SAS.注意:正如肇星所说,您也可以使用 SAS。 But from a programmatic standpoint, assuming you are the storage account owner, that doesn't really buy you much.但从程序化的角度来看,假设您是存储帐户所有者,这并不会真正为您买多少。

The only place Service Principals (and AD in general) comes into play is managing the resource itself (eg the storage account, from a deployment/management/deletion standpoint).服务主体(以及一般的 AD)发挥作用的唯一地方是管理资源本身(例如,从部署/管理/删除的角度来看,存储帐户)。

This is highly confusing.这是非常令人困惑的。 Once a service principal (SP) is registered in azure portal with a new secret created...一旦服务主体 (SP) 在 azure 门户中注册并创建了新的机密...

在此处输入图片说明

...assigned Contributor role at the Resource Group level... ...在资源组级别分配的Contributor角色...

在此处输入图片说明

...any storage accounts and containers therein inherit this role. ...其中的任何存储帐户和容器都会继承此角色。

在此处输入图片说明

在此处输入图片说明

In your application, you can create ServicePrincipalCredentials() and a ClientSecretCredential() from the registered SP...在您的应用程序中,您可以从注册的 SP 创建ServicePrincipalCredentials()和一个ClientSecretCredential() ...

service_credential = ServicePrincipalCredentials(
    tenant = '<yourTenantID>',
    client_id = '<yourClientID>',
    secret = '<yourClientSecret>'
)

client_credential = ClientSecretCredential(
    '<yourTenantID>',
    '<yourClientID>',
    '<yourClientSecret>'
)

From here, create a ResourceManagementClient() ...从这里,创建一个ResourceManagementClient() ...

resource_client = ResourceManagementClient(service_credential, subscription_id)

...to list RG's, Resources and Storage Accounts. ...列出 RG、资源和存储帐户。

for item in resource_client.resource_groups.list():
    print(item.name)

for item in resource_client.resources.list():
    print(item.name + " " + item.type)

for item in resource_client.resources.list_by_resource_group('azureStorage'):
    print(item.name)

BUT...from my research, you cannot list blob containers nor blobs within a given container using ResourceManagementClient() !!.但是...根据我的研究,您不能使用ResourceManagementClient()来列出 Blob 容器或给定容器内的 Blob !!。 So we move to a BlobServiceClient()所以我们转到BlobServiceClient()

blob_service_client = BlobServiceClient(account_url = url, credential=client_credential)

From here, you can list blob containers...从这里,您可以列出 Blob 容器...

blob_list = blob_service_client.list_containers()
for blob in blob_list:
    print(blob.name + " " + str(blob.last_modified))

BUT... From my research, you cannot list blobs within a container!!!但是...根据我的研究,您不能在容器中列出 Blob !!!

container_client = blob_service_client.get_container_client('testcontainer')

blob_list = container_client.list_blobs()
for blob in blob_list:
    print("\t" + blob.name)

---------------------------------------------------------------------------
StorageErrorException                     Traceback (most recent call last)
~/anaconda3_501/lib/python3.6/site-packages/azure/storage/blob/_models.py in _get_next_cb(self, continuation_token)
    599                 cls=return_context_and_deserialized,
--> 600                 use_location=self.location_mode)
    601         except StorageErrorException as error:

~/anaconda3_501/lib/python3.6/site-packages/azure/storage/blob/_generated/operations/_container_operations.py in list_blob_flat_segment(self, prefix, marker, maxresults, include, timeout, request_id, cls, **kwargs)
   1142             map_error(status_code=response.status_code, response=response, error_map=error_map)
-> 1143             raise models.StorageErrorException(response, self._deserialize)
   1144 

StorageErrorException: Operation returned an invalid status 'This request is not authorized to perform this operation using this permission.'

During handling of the above exception, another exception occurred:

HttpResponseError                         Traceback (most recent call last)
<ipython-input-104-7517e7a6a19f> in <module>
      1 container_client = blob_service_client.get_container_client('testcontainer')
      2 blob_list = container_client.list_blobs()
----> 3 for blob in blob_list:
      4     print("\t" + blob.name)

~/anaconda3_501/lib/python3.6/site-packages/azure/core/paging.py in __next__(self)
    120         if self._page_iterator is None:
    121             self._page_iterator = itertools.chain.from_iterable(self.by_page())
--> 122         return next(self._page_iterator)
    123 
    124     next = __next__  # Python 2 compatibility.

~/anaconda3_501/lib/python3.6/site-packages/azure/core/paging.py in __next__(self)
     72             raise StopIteration("End of paging")
     73 
---> 74         self._response = self._get_next(self.continuation_token)
     75         self._did_a_call_already = True
     76 

~/anaconda3_501/lib/python3.6/site-packages/azure/storage/blob/_models.py in _get_next_cb(self, continuation_token)
    600                 use_location=self.location_mode)
    601         except StorageErrorException as error:
--> 602             process_storage_error(error)
    603 
    604     def _extract_data_cb(self, get_next_return):

~/anaconda3_501/lib/python3.6/site-packages/azure/storage/blob/_shared/response_handlers.py in process_storage_error(storage_error)
    145     error.error_code = error_code
    146     error.additional_info = additional_data
--> 147     raise error
    148 
    149 

HttpResponseError: This request is not authorized to perform this operation using this permission.
RequestId:e056fe39-b01e-0007-425c-20a63f000000
Time:2020-05-02T08:32:02.2204809Z
ErrorCode:AuthorizationPermissionMismatch
Error:None

The only way I've found to list blobs within a container (and to do other things like copy blobs, etc), is to create the BlobServiceClient using a Connection String rather than TenantID, ClientID, ClientSecret .我发现在容器中列出 Blob(以及执行其他操作,例如复制 Blob 等)的BlobServiceClient方法是使用连接字符串而不是TenantID, ClientID, ClientSecret创建BlobServiceClient

There is some more info about using a token to access blob resources here and here and here , but I havent' been able to test yet.还有一些关于使用令牌访问 blob 资源的更多信息here and here and here ,但我还没有能够测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM