I am trying to copy a blob from one container to another and am creating a BlobServiceClient using a connection string as described here. However I am running into the following error.
Error performing copyoperation from 'blbcon-common-customer-documents'. Exception: Server failed to authenticate the request. Please refer to the information in the www-authenticate header.
[2024-07-18T16:29:37.783Z] RequestId:bbb336a3-701e-0107-7b2f-d9ff2a000000
[2024-07-18T16:29:37.783Z] Time:2024-07-18T16:29:37.7805609Z
[2024-07-18T16:29:37.783Z] ErrorCode:CannotVerifyCopySource
[2024-07-18T16:29:37.783Z] copysourcestatuscode:401
[2024-07-18T16:29:37.783Z] copysourceerrorcode:NoAuthenticationInformation
[2024-07-18T16:29:37.783Z] copysourceerrormessage:Server failed to authenticate the request. Please refer to the information in the www-authenticate header
I tried using a SAS Token and with the SAS Token the code works perfectly but I want to deploy the function without a SAS Token. Why is the connection string not enough to authenticate? I am using the start_copy_from_url function as described here. The operation works when the url is created using this code:
sas_token = os.getenv("VSN_SAS_Token")
vsn_blob_url = f"{vsn_blob_client.url}?{sas_token}"
However, it does not work when just doing the following where the blob_client is generated with a correct connection string.
vsn_blob_url = vsn_blob_client.url
How can I perform the copy operation using the connection string?
1
When container has private access level then it can only be accessed using SAS key or SAS URL. It is by default private and access level is disabled.
To use start_copy_from_url
access level should be changed to either blob or container.
To change access level:
- Go to
Configuration
of storage and enable allow blob anonymous access - Change container’s access level
To copy from one container to another, upload_from_url
method can be used.
Below code worked for me.
import azure.functions as func
import logging
from azure.storage.blob import BlobServiceClient
app = func.FunctionApp()
@app.route(route="http_trigger", auth_level=func.AuthLevel.ANONYMOUS)
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
connectionString= "DefaultEndpointsProtocol=https;AccountName=vivekrg8272;AccountKey=xxxxxxxxxxxxxxxxxxxxxx;EndpointSuffix=core.windows.net"
serviceClient=BlobServiceClient.from_connection_string(connectionString)
source_blobClient=serviceClient.get_blob_client(container="container1",blob="oldfile.txt")
destination_blobClient=serviceClient.get_blob_client(container="container2", blob="oldfile.txt")
destination_blobClient.upload_blob_from_url(source_url=source_blobClient.url,overwrite=True)
return func.HttpResponse("copied successfully")
OUTPUT
: