【问题标题】:Azure service principal and storage.blob with PythonAzure 服务主体和 storage.blob 与 Python
【发布时间】:2018-06-03 01:13:55
【问题描述】:

我正在尝试通过 python 对服务主体进行身份验证,然后访问 azure.storage.blob

曾经这样做过:

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

但我不能让它与服务主体一起工作:

TENANT_ID = '****'

CLIENT = '****'

KEY_SERVICE = '****'

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

我有点困惑如何将这两个配对,无论我尝试什么,当我尝试上传 blob 时都会让我超时。

【问题讨论】:

    标签: python azure azure-storage service-principal


    【解决方案1】:

    我认为 Azure 存储服务不支持服务主体凭据。实际上它目前只接受两种凭证:共享密钥和共享访问签名(SAS)。

    【讨论】:

      【解决方案2】:

      Azure 存储专门使用帐户名称 + 密钥(无论是主要还是次要)。没有服务主体/基于 AD 的访问的概念。

      您的第一个示例(设置 blob 服务端点)使用帐户名 + 密钥是正确的操作方式。

      注意:正如肇兴所说,您也可以使用 SAS。但从编程的角度来看,假设您是存储帐户的所有者,这并不能真正为您带来太多收益。

      服务主体(以及一般的 AD)发挥作用的唯一地方是管理资源本身(例如,从部署/管理/删除的角度来看,存储帐户)。

      【讨论】:

      • 我尝试使用服务主体的原因是它是一个 24/7 运行的脚本。并且 atm 工作正常,直到第二天早上我必须通过 Azure 门户登录才能在一天的剩余时间里验证我的 python 请求。
      【解决方案3】:

      这非常令人困惑。 在 Azure 门户中注册服务主体 (SP) 并创建新机密后...

      ...在资源组级别分配Contributor 角色...

      ...其中的任何存储帐户和容器都会继承此角色。

      在您的应用程序中,您可以从注册的 SP 中创建 ServicePrincipalCredentials()ClientSecretCredential()...

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

      从这里,创建一个ResourceManagementClient()...

      resource_client = ResourceManagementClient(service_credential, subscription_id)
      

      ...列出 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)
      

      但是...根据我的研究,您不能使用ResourceManagementClient()!! 列出给定容器中的 blob 容器或 blob。所以我们转移到BlobServiceClient()

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

      从这里,您可以列出 blob 容器...

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

      但是...根据我的研究,您不能在容器中列出 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
      

      我发现在容器中列出 blob(以及执行复制 blob 等其他操作)的唯一方法是使用连接字符串而不是 TenantID, ClientID, ClientSecret 创建 BlobServiceClient

      还有一些关于使用令牌访问 blob 资源 hereherehere 的更多信息,但我还没有能够测试。

      【讨论】:

      • 我正在处理同样的事情,发现服务原则的存储帐户上的“协作者”角色不是正确的角色 - 您需要具有“存储 Blob 数据贡献者”角色已分配。
      猜你喜欢
      • 2021-05-05
      • 1970-01-01
      • 2020-12-27
      • 2018-06-14
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多