Azure Blob Storage Container properties using Account SAS - Authentication Failed

58 Views Asked by At

I've manged to generate a Service SAS to list the blobs within my container, however I'm unable to get the container properties using an Account SAS, this is the error I get back:

<?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:63a5ec3b-601e-0016-4e07-4a125b000000
Time:2024-01-18T12:08:26.1877828Z</Message>
    <AuthenticationErrorDetail>Signature did not match. String to sign used was devreferenceapidatasa
rwl
b
sc
2024-01-18T12:07:27Z
2024-01-18T12:17:27Z

https
2023-11-03

</AuthenticationErrorDetail>
</Error>

I've followed the Azure documentation: https://learn.microsoft.com/en-us/rest/api/storageservices/create-account-sas https://learn.microsoft.com/en-us/rest/api/storageservices/get-container-properties?tabs=microsoft-entra-id

This is my JS code

var accountName = "reference-data";
var signedPermissions = "rwl";
var signedService = "b";
var signedStart = start;
var signedExpiry = end;
var signedResourceType = "sc";
var signedProtocol = "https";
var signedVersion = "2023-11-03";

function generateSas(storageAccountKey, input) {
    input = decodeURI(input)
    const keyBytes = CryptoJS.enc.Base64.parse(storageAccountKey)
    const hash = CryptoJS.HmacSHA256(input, keyBytes)
    const hashB64 = CryptoJS.enc.Base64.stringify(hash)
    const hashB64UriEncoded = encodeURIComponent(hashB64)
    
    return hashB64UriEncoded
}

var stringToSign = accountName + "\n" +  
    signedPermissions + "\n" +  
    signedService + "\n" +  
    signedResourceType + "\n" +  
    signedStart + "\n" +  
    signedExpiry + "\n" +  
    signedProtocol + "\n" +  
    signedVersion + "\n"

var key = MY_KEY;

const sig = generateSas(key, stringToSign)
var sasToken = `sv=${signedVersion}&ss=${signedService}&srt=${signedResourceType}&sp=${signedPermissions}&st=${signedStart}&se=${signedExpiry}&spr=${signedProtocol}&sig=${sig}`;

var url = `https://devreferenceapidatasa.blob.core.windows.net/reference-data?restype=container&${sasToken}`
1

There are 1 best solutions below

0
Gaurav Mantri On

Based on the documentation here, the format of the string to sign should be:

StringToSign = accountname + "\n" +  
    signedpermissions + "\n" +  
    signedservice + "\n" +  
    signedresourcetype + "\n" +  
    signedstart + "\n" +  
    signedexpiry + "\n" +  
    signedIP + "\n" +  
    signedProtocol + "\n" +  
    signedversion + "\n"

If you notice, you are missing signedIP in your code. Please try by changing your code to something like the following:

var accountName = "reference-data";
var signedPermissions = "rwl";
var signedService = "b";
var signedStart = start;
var signedExpiry = end;
var signedIP = "";//add signed IP
var signedResourceType = "sc";
var signedProtocol = "https";
var signedVersion = "2023-11-03";

function generateSas(storageAccountKey, input) {
    input = decodeURI(input)
    const keyBytes = CryptoJS.enc.Base64.parse(storageAccountKey)
    const hash = CryptoJS.HmacSHA256(input, keyBytes)
    const hashB64 = CryptoJS.enc.Base64.stringify(hash)
    const hashB64UriEncoded = encodeURIComponent(hashB64)
    
    return hashB64UriEncoded
}

var stringToSign = accountName + "\n" +  
    signedPermissions + "\n" +  
    signedService + "\n" +  
    signedResourceType + "\n" +  
    signedStart + "\n" +  
    signedExpiry + "\n" +  
    signedIP + "\n" +
    signedProtocol + "\n" +  
    signedVersion + "\n"

var key = MY_KEY;

const sig = generateSas(key, stringToSign)
var sasToken = `sv=${signedVersion}&ss=${signedService}&srt=${signedResourceType}&sp=${signedPermissions}&st=${signedStart}&se=${signedExpiry}&spr=${signedProtocol}&sig=${sig}`;

var url = `https://devreferenceapidatasa.blob.core.windows.net/reference-data?restype=container&${sasToken}`