Share via

User Delegated SAS Token for Blob Store in Python

Mike Pfaffenberger 1 Reputation point
2021-09-07T14:44:14.097+00:00

Hi Everyone,

I'm having some trouble creating user delegated SAS tokens for my Azure blobstore accounts. The following code simply hangs for a bit and eventually throws an error:

from azure.storage.blob import (
    BlobServiceClient,
    generate_account_sas,
    ResourceTypes,
    AccountSasPermissions,
)
from azure.identity import (
    AzureCliCredential,
    DeviceCodeCredential,
    DefaultAzureCredential,
)
from azure.storage.blob import generate_container_sas
from azure.storage.blob import BlobServiceClient

storage_account = "my_account"
container = "my_container"

cli_credential = DeviceCodeCredential()
blob_service_client = BlobServiceClient(
    account_url="https://{storage_acct}.blob.core.windows.net".format(
        storage_acct=storage_account
    ),
    credential=cli_credential,
)
delegation_key = blob_service_client.get_user_delegation_key(
    datetime.now(), datetime.now() + timedelta(days=1), timeout=5
)

Here is the output:

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code EES5Q8WS6 to authenticate.
---------------------------------------------------------------------------
ServiceRequestError                       Traceback (most recent call last)
/var/folders/c9/bk6h021d3xq0fw148myyb9kc0000gp/T/ipykernel_80291/4132771656.py in <module>
     14     credential=cli_credential
     15 )
---> 16 blob_service_client.get_user_delegation_key(datetime.now(), datetime.now() + timedelta(days=1), timeout=5)

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/tracing/decorator.py in wrapper_use_tracer(*args, **kwargs)
     81             span_impl_type = settings.tracing_implementation()
     82             if span_impl_type is None:
---> 83                 return func(*args, **kwargs)
     84 
     85             # Merge span is parameter is set, but only if no explicit parent are passed

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/storage/blob/_blob_service_client.py in get_user_delegation_key(self, key_start_time, key_expiry_time, **kwargs)
    201             user_delegation_key = self._client.service.get_user_delegation_key(key_info=key_info,
    202                                                                                timeout=timeout,
--> 203                                                                                **kwargs)  # type: ignore
    204         except HttpResponseError as error:
    205             process_storage_error(error)

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/storage/blob/_generated/operations/_service_operations.py in get_user_delegation_key(self, key_info, timeout, request_id_parameter, **kwargs)
    435         body_content_kwargs['content'] = body_content
    436         request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs)
--> 437         pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
    438         response = pipeline_response.http_response
    439 

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in run(self, request, **kwargs)
    209             else _TransportRunner(self._transport)
    210         )
--> 211         return first_node.send(pipeline_request)  # type: ignore

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/policies/_redirect.py in send(self, request)
    156         redirect_settings = self.configure_redirects(request.context.options)
    157         while retryable:
--> 158             response = self.next.send(request)
    159             redirect_location = self.get_redirect_location(response)
    160             if redirect_location and redirect_settings['allow']:

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/storage/blob/_shared/policies.py in send(self, request)
    513                     self.sleep(retry_settings, request.context.transport)
    514                     continue
--> 515                 raise err
    516         if retry_settings['history']:
    517             response.context['history'] = retry_settings['history']

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/storage/blob/_shared/policies.py in send(self, request)
    487         while retries_remaining:
    488             try:
--> 489                 response = self.next.send(request)
    490                 if is_retry(response, retry_settings['mode']):
    491                     retries_remaining = self.increment(

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/policies/_authentication.py in send(self, request)
    117         self.on_request(request)
    118         try:
--> 119             response = self.next.send(request)
    120             self.on_response(request, response)
    121         except Exception:  # pylint:disable=broad-except

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/storage/blob/_shared/policies.py in send(self, request)
    288             request.context.options.pop('raw_response_hook', self._response_callback)
    289 
--> 290         response = self.next.send(request)
    291         will_retry = is_retry(response, request.context.options.get('mode'))
    292         if not will_retry and download_stream_current is not None:

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
     69         _await_result(self._policy.on_request, request)
     70         try:
---> 71             response = self.next.send(request)
     72         except Exception:  # pylint: disable=broad-except
     73             if not _await_result(self._policy.on_exception, request):

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/_base.py in send(self, request)
    101         return PipelineResponse(
    102             request.http_request,
--> 103             self._sender.send(request.http_request, **request.context.options),
    104             context=request.context,
    105         )

~/anaconda3/envs/pyspark-test/lib/python3.7/site-packages/azure/core/pipeline/transport/_requests_basic.py in send(self, request, **kwargs)
    296 
    297         if error:
--> 298             raise error
    299         return RequestsTransportResponse(request, response, self.connection_config.data_block_size)

ServiceRequestError: <urllib3.connection.HTTPSConnection object at 0x7fc3e85c69d0>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known

Could someone please explain to me how to correctly generate a user delegated SAS token using Azure SDK?

Thank you.

Azure Blob Storage
Azure Blob Storage

An Azure service that stores unstructured data in the cloud as blobs.

Microsoft Security | Microsoft Entra | Microsoft Entra ID

1 answer

Sort by: Most helpful
  1. Anonymous
    2021-09-08T21:50:34.093+00:00

    @Mike Pfaffenberger
    There is a good thread on Stackoverflow with some code to generate a user delegated SAS token. There is another example on the GitHub issues page which might be helpful.

    Please give these a try to see if they work for you. If not please let us know and we will be happy to assist further.

    -------------------------------

    Please don’t forget to "Accept the answer" and “up-vote” wherever the information provided helps you, this can be beneficial to other community members.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.