c# - Azure Blob 存储共享访问签名 (SAS) - 签名不匹配

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

我尝试通过将 ARM 模板和参数文件上传到私有(private) Blob 存储容器中来部署虚拟机,然后在需要时下载它们。文件上传到容器中很好,但是当尝试下载它们时,SAS token 无法进行身份验证,并给出错误:

Microsoft.Rest.Azure.CloudException: 
Unable to download deployment content from 'https://cloudstationsbackendsa.blob.core.windows.net/workstation-templates/CreateVMTemplate.json?sv=2018-03-28&sr=b&sig=GHgWUiEG7bG3%2FDN4cjSsmHGrBTdM8F2LRxNTss5cJB0%3D&st=2019-03-06T11:16:42Z&se=2019-03-06T11:31:42Z&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 token 的方法:

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 token 附加到 blob 的 URI 并在 StorageAccountAccessDTO 中返回,这将传递到以下方法以生成 VM:

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();
}

感谢您抽出宝贵的时间,如果您需要任何额外的详细信息,请告诉我!

最佳答案

您正在尝试将 templateBlob 的 URL 与 parameterBlob 的签名一起使用。

就在那里:

ParametersURL = templateBlob.Uri + parameterBlob.GetSharedAccessSignature(sasConstraints)

使用正确的变量会更好:

ParametersURL = parameterBlob.Uri + parameterBlob.GetSharedAccessSignature(sasConstraints)

干杯!

关于c# - Azure Blob 存储共享访问签名 (SAS) - 签名不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55021904/

相关文章:

c# - 对象到 IQueryable

C# 防火墙,删除特定条目

azure - 如何将变量传递给 azure devops 管道中的 SqlAzureDacpacDeployment@1 任务

php - 通过 azure graph api 更新时权限不足,无法完成操作

c# - .Net Standard 中 CompileToMethod 的替代方案

c# - 从 UWP BackgroundTask 调用 MediaCapture.InitializeAsync

c# - 以编程方式使用 Sandbox 的 azure CreateNotificationHub

azure - Windows Azure 本地 Blob 存储访问?

c# - 给定分区键列表,在表存储中查找匹配记录

asp.net-mvc - 从 MVC3 迁移到 MVC4 和 Azure 1.7 - 为什么 iisexpress.exe 现在出现在日志文件中