Home > other >  Problems generating a SAS token in C# for Blob paths with special characters
Problems generating a SAS token in C# for Blob paths with special characters

Time:07-17

We are implementing a file store in our application and we store all the files in private containers in Azure Blob Storage. We have a virtual folder system which we replicate in our Blob storage.

For example, Let's say i work for Company A, and i upload file_1.txt to Folder #1, it will reside in /vault/Company A/Folder #1/file_1.txt in the Blob storage.

We generate SAS tokens using the following code:

public  static Uri GetServiceSasUriForCloudBlockBlob(CloudBlockBlob cloudBlockBlob, string permissions = "r")
{
            
    var sasBuilder = new SharedAccessBlobPolicy()
    {
        SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
        SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(5),
        Permissions = SharedAccessBlobPolicy.PermissionsFromString(permissions)
    };
            
    var sasUri = cloudBlockBlob.GetSharedAccessSignature(sasBuilder);

    return new Uri(cloudBlockBlob.Uri   sasUri);

}

However, this does not work. The error we get is:

<Error>
    <script type="text/javascript"/>
    <Code>AuthenticationFailed</Code>
    <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:f82118d1-101e-002a-1381-97ac16000000 Time:2022-07-14T12:55:34.6370028Z</Message>
    <AuthenticationErrorDetail>Signature did not match. String to sign used was r 2022-07-14T12:50:27Z 2022-07-14T13:00:27Z /blob/[blobname]/vault/Company A/Folder #1/file_1.txt 2019-07-07 b </AuthenticationErrorDetail>
</Error>

When generating a SAS token from the Azure Portal or the Azure Storage Explorer there is no problem

It seems to be an issue with the special characters in the path to the file in the Blob. So we tried escaping all spaces and special characters manually to fix this issue, however when doing this the CloudBlockBlob encodes it again (e.g.: it escapes My File.txt to My%20File.txt).

Currently the only operation we use is Read on Objects, but this may be expanded in the future.

We could disallow spaces and special character in folders/files but this doesn't feel like solving the issue but working around it. How can we fix this without implementing naming policies?

EDIT: Turns out this was a design issue, and while the SDK docs never explicitly disencourages the use unescaped blob paths it does disallow container names with anything other than alphanumerics and dashes.

CodePudding user response:

For anyone having the same issue (whether on SDK version 11 or 12), i can highly recommend not using spaces/special characters without encoding them part by part,

var fileName = "file.txt"

// Note that the order here matters
var folderNames = ["Folder #1", "Folder #1.1"]

// becomes: Folder %231/Folder %231.1
var encodedPath = folderNames.Select(WebUtility.UrlEncode).Aggregate((x, y) => x   "/"   y);

// becomes: Folder %231/Folder %231.1/file.txt
var blobPath = ${encodedPath}/{fileName}"

This looks worse in Azure Storage Explorer but this does circumvent issues with encoding string programmatically

  • Related