Подпись общего доступа к хранилищу больших двоичных объектов Azure (SAS) — подпись не соответствует

#c# #azure #azure-storage #azure-blob-storage #azure-sdk-.net

#c# #azure #azure-хранилище #azure-blob-storage #azure-sdk-.net

Вопрос:

Я пытаюсь развернуть виртуальную машину, загрузив шаблон ARM и файл параметров в частный контейнер для хранения больших двоичных объектов, а затем загрузить их при необходимости. Файлы загружаются в контейнер нормально, но при попытке загрузить их токен SAS не проходит проверку подлинности, выдавая ошибку:

 Microsoft.Rest.Azure.CloudException: 
Unable to download deployment content from 'https://cloudstationsbackendsa.blob.core.windows.net/workstation-templates/CreateVMTemplate.json?sv=2018-03-28amp;sr=bamp;sig=GHgWUiEG7bG3/DN4cjSsmHGrBTdM8F2LRxNTss5cJB0=amp;st=2019-03-06T11:16:42Zamp;se=2019-03-06T11:31:42Zamp;sp=r'
  

При посещении этого URL-адреса в браузере возникает следующая ошибка:

 <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:8e274bc1-101e-0011-3f0c-d45f43000000 Time:2019-03-06T11:03:53.3144543Z
</Message>
<AuthenticationErrorDetail>
Signature did not match. String to sign used was r 2019-03-06T10:58:39Z 2019-03-06T11:13:39Z /blob/cloudstationsbackendsa/workstation-templates/CreateVMTemplate.json 2018-03-28
</AuthenticationErrorDetail>
</Error>
  

Этот метод используется для загрузки файлов и генерации токенов SAS:

 public async Task<StorageAccountAccessDTO> UploadTemplatesAsync(string azureIdentifier)
{
    // Access to Storage Account           
    var account = CloudStorageAccount.Parse(_config.GetValue<string>("ConnectionStrings:StorageAccount"));
    var serviceClient = account.CreateCloudBlobClient();
    var container = serviceClient.GetContainerReference("workstation-templates");

    // Upload VM ARM Template
    var templateBlob = container.GetBlockBlobReference("CreateVMTemplate.json");
    await templateBlob.UploadFromFileAsync("CreateVMTemplate.json");

    // Upload VM ARM Parameters
    var parameterBlob = container.GetBlockBlobReference("Parameters.json");
    await parameterBlob.UploadFromFileAsync("Parameters.json");

    // Create SAS Tokens
    SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
    sasConstraints.SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5);
    sasConstraints.SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(10);
    sasConstraints.Permissions = SharedAccessBlobPermissions.Read;

    var accessDTO = new StorageAccountAccessDTO()
    {
        TemplateURL = templateBlob.Uri   templateBlob.GetSharedAccessSignature(sasConstraints),
        ParametersURL = templateBlob.Uri   parameterBlob.GetSharedAccessSignature(sasConstraints)
    };

    return accessDTO;
}
  

Токены SAS добавляются к URI большого двоичного объекта и возвращаются в StorageAccountAccessDTO, это передается в описанный ниже метод для создания виртуальной машины:

 public async Task CreateVirtualMachineAsync(string azureIdentifier, StorageAccountAccessDTO accessDTO)
{
    await _azure.Deployments.Define("myDeployment")
        .WithExistingResourceGroup(azureIdentifier   "-RG")
        .WithTemplateLink(accessDTO.TemplateURL, "1.0.0.0")
        .WithParametersLink(accessDTO.ParametersURL, "1.0.0.0")
        .WithMode(DeploymentMode.Incremental)
        .CreateAsync();
}
  

Спасибо за ваше время и дайте мне знать, если вам потребуются какие-либо дополнительные сведения!

Комментарии:

1. Что происходит, когда вы пытаетесь загрузить большой двоичный объект напрямую, используя SAS URL, т. е. берете SAS URL и вставляете его в адресную строку браузера? Вы получаете сообщение об ошибке?

2. @GauravMantri Да, на самом деле именно оттуда я извлек ошибку XML, я обновил вопрос, включив исходную ошибку, которую я получил из кода для ясности. Спасибо за предложение!

Ответ №1:

Вы пытаетесь использовать URL templateBlob с подписью для parameterBlob .

Прямо здесь:

 ParametersURL = templateBlob.Uri   parameterBlob.GetSharedAccessSignature(sasConstraints)
  

Это будет работать лучше с правильной переменной:

 ParametersURL = parameterBlob.Uri   parameterBlob.GetSharedAccessSignature(sasConstraints)
  

Приветствия!

Комментарии:

1. Должно быть, я пропустил этот поиск проблемы с templateUrl, он пытается загрузить большой двоичный объект шаблона во второй раз для параметров вместо файла шаблона, глупая ошибка с моей стороны, спасибо за помощь!