Reputation: 3947
I am trying to return a SAS url to my frontend so I can redirect the user to that link and so they can download the file.
This is my code to create the SAS url
private SasQueryParameters GenerateSaSCredentials(string containerName, string blobName) {
// Defines the resource being accessed and for how long the access is allowed.
BlobSasBuilder blobSasBuilder = new() {
StartsOn = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(10)),
ExpiresOn = DateTime.UtcNow.Add(TimeSpan.FromMinutes(120)) + TimeSpan.FromSeconds(1),
Resource = "b",
BlobName = blobName,
BlobContainerName = containerName
};
// Defines the type of permission.
blobSasBuilder.SetPermissions(BlobSasPermissions.Read);
// Builds an instance of StorageSharedKeyCredential
StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _key);
// Builds the Sas URI.
return blobSasBuilder.ToSasQueryParameters(storageSharedKeyCredential);
}
public Uri CreateBlobUri(string blobName, string containerName) {
SasQueryParameters parameters = GenerateSaSCredentials(containerName, blobName);
return new UriBuilder {
Scheme = "https",
Host = $"{_accountName}.blob.core.windows.net",
Path = $"files/{containerName}/{blobName}",
Query = WebUtility.UrlDecode(parameters.ToString())
}.Uri;
}
You may notice the url decode on parameters.ToString() is because of a similar issue ive seen on stackoverflow where they spoke of double encoding.
However when i return this url to the browser and redirect i get the following error.
This is how i return the URL
return Ok(_blobUtils.CreateBlobUri(fileName, containerName).ToString());
<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:01696cca-d01e-0023-2ea4-74f5df000000
Time:2021-07-09T09:23:33.0250817Z</Message>
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
</Error>
If i remove the WebUtility.UrlDecode from the parameters.ToString()
, i get this error
<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:016a1821-d01e-0023-3da4-74f5df000000
Time:2021-07-09T09:24:38.4051042Z</Message>
<AuthenticationErrorDetail>Signature did not match. String to sign used was r 2021-07-
09T09:14:38Z 2021-07-09T11:24:39Z /blob/${_acountName}/files/bqXbY54sRRsipOUB1PF6/fyI67FYOqDS80y1vNWRL/PRE_OP_CT/0/TK1.left.TST.PTN1.PRE
_OP_CT.zip 2020-04-08 b </AuthenticationErrorDetail>
</Error>
The structure of the Blob i am trying to access is:
And finally the blob we are trying to create a SAS to
Can anyone see why this would fail?
Upvotes: 2
Views: 1025
Reputation: 136346
Please get rid of files
from Path
here:
return new UriBuilder {
Scheme = "https",
Host = $"{_accountName}.blob.core.windows.net",
Path = $"files/{containerName}/{blobName}",
Query = WebUtility.UrlDecode(parameters.ToString())
}.Uri;
It should be something like:
return new UriBuilder {
Scheme = "https",
Host = $"{_accountName}.blob.core.windows.net",
Path = $"{containerName}/{blobName}",
Query = WebUtility.UrlDecode(parameters.ToString())
}.Uri;
UPDATE
Based on the screenshot and the error message, the name of your container is files
and the name of the blob is bqXbY54sRRsipOUB1PF6/fyI67FYOqDS80y1vNWRL/PRE_OP_CT/0/TK1.left.TST.PTN1.PRE
. Please use them in your code and you should not get the error. You still need to remove files
from the Path above as it is already included in your containerName
.
The reason your code is failing is because you're calculating SAS token for a blob inside a blob container (the blob path becomes container-name/blob-name
). However in your request, you're prepending files
to your request URL, your blob path becomes files/container-name/blob-name
. Since the SAS token is obtained for a different path but is used for another path, you're getting the error.
Upvotes: 2