将文件放入没有 ContentLength 的 Azure Blob

PUT File to Azure Blob without ContentLength

我在一家公司工作,希望他们能够将文件放入我的 Azure Blobstorage。我的想法是我生成授权 header 并使用他们的 REST API 将此和其他所需的 header 传递给他们。然后他们使用它把文件放到我的 Azure 容器中。

问题是我不知道他们要放置的文件的大小。在我所有的研究和使用 Postman 进行的测试中,我必须知道文件的大小,以便在创建授权时设置 ContentLength Header。只有这样 PUT 才会成功。我的授权 header 格式如下:

SharedKey storagename:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=
  1. 是否可以在不知道 ContentLength 的情况下创建授权 header?
  2. 如果没有,是否有另一种方法将文件放入或发布到 blob(或 Azure 文件,如果这更有可能成功)?

我相信你想的方法行不通。

首先,你在计算授权时需要指定内容长度header,你显然不知道。

其次,当您计算授权时 header 您必须指定当前日期时间(在 Datex-ms-date header 中)。您将 运行 遇到的问题是,如果几乎没有立即使用授权 header,您的客户的请求将被拒绝。

对您来说更好的选择是在获得 Write 许可的情况下使用 Shared Access Signature。在那里你不必担心包括内容长度。您的用户只需使用共享访问签名 URL 即可将文件上传到您的 blob 容器中。您可能希望为您希望用户上传文件的 blob 容器创建一个 SAS URL。

正如@GuaravMantri 所说(并且正如我所怀疑的那样),在使用将用于使用 SharedKey 进行 PUT 的授权 header 创建文件时,内容长度是必不可少的。我还没有想到他提到的第二个问题,link 会在使用前过期。

所以这就是我最终在 C# 中使用共享访问签名生成 url 的方法:

        string blobName = $"TestFile.txt";
        string storageAccountName = "aaaaaaaa";
        string containerName = "ccccccccc";
        string key = "kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk==";

        string connectionString = $"DefaultEndpointsProtocol=https;AccountName={storageAccountName};AccountKey={key}";
        BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
        BlobClient blob = containerClient.GetBlobClient(blobName);

        var sasBuilder = new Azure.Storage.Sas.BlobSasBuilder()
        {
            BlobContainerName = containerName,
            BlobName = blobName,
            Resource = "b",  
            StartsOn = DateTime.UtcNow.AddMinutes(-5),
            ExpiresOn = DateTime.UtcNow.AddMinutes(120)
        };
        sasBuilder.SetPermissions(Azure.Storage.Sas.BlobSasPermissions.Create);

        StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(storageAccountName, key);
        BlobSasQueryParameters sasQueryParameters = sasBuilder.ToSasQueryParameters(storageSharedKeyCredential);

        UriBuilder fullUri = new UriBuilder()
        {
            Scheme = "https",
            Host = string.Format($"{storageAccountName}.blob.core.windows.net"),
            Path = string.Format($"{containerName}/{blobName}"),
            Query = sasQueryParameters.ToString()
        };

        BlobClient blobClient = new BlobClient(fullUri.Uri, null);

        string uriToUseInPostman = fullUri.Uri.ToString();

我用 Postman 测试了一下:

请注意,我必须设置 x-ms-blob-type。没有这个 header 上传失败。