0

I've been trying to display images from Azure blob storage on my web app for a while now. My storage account SAS token is:

?sv=2021-06-08&ss=bfqt&srt=sco&sp=rwdlacupiytfx&se=2022-12-09T08:03:09Z&st=2022-11-09T08:03:09Z&spr=https&sig=SIGNATURE_HERE

This SAS token includes all permissions and allows all resource types and services.

To generate a SAS token to view a blob, I go through the following steps:

1. Getting the blobService:

const blobService = new BlobServiceClient(https://${storageAccountName}.blob.core.windows.net/?${storageAccountSasToken});

2. Creating a containerClient:

const containerClient = blobService.getContainerClient(containerName);

3. creating a sasOptions object:

const sasOptions = {containerName: containerName, blobName: blobName, startsOn: sasStartTime, expiresOn: sasExpiryTime, permissions: "racwdt" as unknown as BlobSASPermissions};

4. Generating SAS token with the parameters:

generateBlobSASQueryParameters(sasOptions, sharedKeyCredential).toString();

5. Sending the blobURL (with the SAS token attached) back to the user:

const blobURL = containerClient.getBlockBlobClient(blobName).url;

The problem is, when using the blobURL as src for my Image tag, I get a 403 (forbidden) error:

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

the faulty blobURL in question: https://mywebsite.blob.core.windows.net/container/profilePictures%2Fpicture.png?sv=2021-06-08&ss=bfqt&srt=sco&sp=rwdlacupiytfx&se=2022-12-09T08:03:09Z&st=2022-11-09T08:03:09Z&spr=https&sig=CITlY0uPxBCGdBeMtIxxJafJM61HQlhooR5ZnDiPHuE%3D

The Error:

AuthenticationFailed Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:df81f724-f01e-000e-593e-f41f7f000000 Time:2022-11-09T13:24:08.3305270Z Signature did not match. String to sign used was STORAGE_ACCOUNT_NAME racwdt bfqt sc 2022-11-09T12:31:47Z 2022-12-09T20:31:47Z https 2021-06-08

Additional information:

  • The sasToken env variable includes "?" at the start of the string
  • All containers are PRIVATE.
  • My storage account is only accessible through a specific virtual network
  • My website's domain is listed on "Allowed Origins" in CORS tab, as well as localhost:3000
  • Uploading to Blob storage works, So Its safe to assume that the problem is solely related to the generated SAS token

Any assistance would be gladly appreciated :)

Ariel K.
  • 33
  • 7
  • Is the computer from which you are accessing the blob part of the same virtual network? – Gaurav Mantri Nov 09 '22 at 13:00
  • No, but I allowed access for the public IP address of my PC on the "Networking" tab. also ,localhost:3000 is listed in my "Allowed Origins" on the "CORS" tab. – Ariel K. Nov 09 '22 at 13:04
  • Ok. Using SAS token, you are able to upload the blob from your computer. Right? – Gaurav Mantri Nov 09 '22 at 13:07
  • Yes. by using the storage account's SAS token I am able to upload the blob from my PC. – Ariel K. Nov 09 '22 at 13:09
  • Hmmm...Can you edit your question and include the complete error message? Usually Storage Service returns more details about the 403 error. – Gaurav Mantri Nov 09 '22 at 13:16
  • Also, try replacing `%2F` with `/` in your faulty blob URL. – Gaurav Mantri Nov 09 '22 at 13:18
  • I've tried ```replaceAll("%2F","/")``` but to no avail – Ariel K. Nov 09 '22 at 13:27
  • There's definitely something wrong with your SAS token. The permissions in your SAS URL is `rwdlacupiytfx` whereas Storage Service is using `racwdt`. Can you edit your question and include the complete code? – Gaurav Mantri Nov 09 '22 at 13:32
  • I've tried copying ```rwdlacupiytfx``` into the SAS token and vice versa, as well as ```racwdt```. still doesnt work... You should know that yesterday it worked just fine, but then i messed around with rerolling some tokens and changing .env variables... – Ariel K. Nov 09 '22 at 13:41

1 Answers1

0

I tried in my environment and got below results:

Code:

var  storage = require("@azure/storage-blob")
const  accountname ="storage13261";
const  key = "< Account key >";
const  cred = new  storage.StorageSharedKeyCredential(accountname,key);
const  blobServiceClient = new  storage.BlobServiceClient(`https://${accountname}.blob.core.windows.net`,cred);
const  containerName="test";
const  client =blobServiceClient.getContainerClient(containerName)
const  blobName="nature.png"; 
const  blobClient = client.getBlobClient(blobName);
const  blobSAS = storage.generateBlobSASQueryParameters({
containerName,
blobName,
permissions:  storage.BlobSASPermissions.parse("racwdt"),
startsOn:  new  Date(),
expiresOn:  new  Date(new  Date().valueOf() + 86400) 
},
cred
).toString();
const  sasUrl= blobClient.url+"?"+blobSAS;
console.log(sasUrl);

Console:

enter image description here

The problem is in your SAS token where storage service is uses racwdt but in you SAS has rwdlacupiytfx that may cause to display an image.

I checked the Url + SAS token in the browser it perfectly worked.

enter image description here

Reference: Grant limited access to data with shared access signatures (SAS) - Azure Storage | Microsoft Learn

Updated:

You can get both SAS and SAS-URL manually with check the permission by refer the below image.

enter image description here

Venkatesan
  • 3,748
  • 1
  • 3
  • 15
  • Thank you, But I still got some questions- 1. In my sasOptions object I specify the SAS to have ```racwdt``` permissions, so why is it generated with ```rwdlacupiytfx```? 2. Should I initialise a BlobServiceClient with a different parameter, other than my storage account SAS? 3. Should I check only the boxes that refer to r,a,c,w,d,t permissions when manually creating the SAS? If so, what boxes should I tick? 4. In the url which you put in the browser to view the image, what are the permissions? Same as mine or different? – Ariel K. Nov 13 '22 at 06:27
  • Hi @Ariel.K Check the updated answer and also I used the Url which is generated by code and I copied the generated Url & pasted in browser it worked. – Venkatesan Nov 13 '22 at 14:04