[英]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.