简体   繁体   中英

Azure Storage SAS token working on localhost but not when deployed on Azure Kubernetes

I am uploading and downloading files to Azure storage from a React spa using SAS tokens.

When running on localhost, everything works, however when deployed to Kubernetes on Azure, I receive the following authentication error.

onError RestError: <?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:e6bfca97-c01e-0030-2e29-4e7d7c000000
Time:2020-06-29T15:26:39.7164613Z</Message><AuthenticationErrorDetail>Signature did not match. String to sign used was w

2020-06-29T20:26:39Z
/blob/datalake/container/Natural_Language_Processing.pdf

The javascript code responsible for the upload is

// upload to Azure
const blobName = file.name;
const accountSas = resp.data.SAS;
const account = resp.data.account;
const containerName = resp.data.container;
const anonymousCredential = new AnonymousCredential();
const blobServiceClient = new BlobServiceClient(
    `https://${account}.blob.core.windows.net?${accountSas}`,
    anonymousCredential
);
// Create a container
const containerClient = blobServiceClient.getContainerClient(
    containerName
);
// Create a blob
const content = file;
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
const uploadBlobResponse = await blockBlobClient.upload(
    content,
    Buffer.byteLength(content)
);

while the backend Python code for the SAS token generation is the following

if content['up_down'] == 'download':
    permission = BlobSasPermissions(read=True)
else:
    permission = BlobSasPermissions(write=True)

account_name = os.getenv("STORAGE_ACCOUNT_NAME")
container_name = metadata.get_container_name()
blob_name = content['filePath']
expiry = datetime.utcnow() + timedelta(hours=5)

options = {
    'account_name': account_name,
    'container_name': container_name,
    'blob_name': blob_name,
    'account_key': os.getenv("STORAGE_ACCESS_KEY"),
    'permission': permission,
    'expiry': expiry
}

SAS = generate_blob_sas(**options)

Where generate_blob_sas is imported from azure-storage-blob (version 12.3.1).

Any idea on how to resolve this?

After a long time scratching my head to find a solution, I figured out where the problem was.

It had nothing to do with the Python library for accessing the blob, but rather with the environment variables in the Kubernetes pod.

The environment variables were passed to Kubernetes as secrets using a yaml file (as explained in this link ). Using this method, the secret needs to be base64 encoded. For this I was using the following

echo 'secret' | base64
>> c2VjcmV0Cg==

In this way however, the echo command appends by default a newline character to the output. What I should have used instead was

echo -n 'secret' | base64
>> c2VjcmV0

This bug was particularly difficult to find especially because when printed, the wrong solution would appear to lead to the correct result

echo 'secret' | base64 | base64 -d
>> secret

Anyway, I hope that my mistake will help someone in the future!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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