【问题标题】:Azure Blob returning 403 on uploadAzure Blob 在上传时返回 403
【发布时间】:2020-05-10 10:26:31
【问题描述】:

我有一个 azure 函数,它生成一个 sas 密钥,我稍后会使用该密钥将文件上传到我的 blob。这是我生成 sas 密钥的方式:

CloudBlobContainer container = blobClient.GetContainerReference("sasimagecontainer");
container.CreateIfNotExists();

static string GetContainerSasUri(CloudBlobContainer container)
{
    //Set the expiry time and permissions for the container.
    //In this case no start time is specified, so the shared access signature becomes valid immediately.
    SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
    sasConstraints.SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5);
    sasConstraints.SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(25);
    sasConstraints.Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Add | SharedAccessBlobPermissions.Create;

    //Generate the shared access signature on the container, setting the constraints directly on the signature.
    string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);

    //Return the URI string for the container, including the SAS token.
    return container.Uri + sasContainerToken + "&comp=list&restype=container";
}

然后我就可以打电话了

GetContainerSasUri(容器));

获取 sas 密钥。但是当我使用下面的代码来调用它时:

CloudBlockBlob blob = new CloudBlockBlob(thesaskey);
using (var fileStream = File.OpenRead(file))
{
    await blob.UploadFromStreamAsync(fileStream);
}

我不断收到 403 错误。这就是我在 VS 2017 中调试所获得的全部信息,我不确定如何获取有关此问题的更多信息。

我已经在 SO 上查看了关于类似问题的大多数类似线程并应用了可能的修复,例如末尾的“&comp=list&restype=container”参数。

// 我尝试将 SharedAccessBlobPermissions.List 添加到权限中,但没有成功。

// 我确实添加了所有权限(当然,无权限除外)以检查这是否会改变某些东西 - 它不会。目标仍然是只有上传权限。

【问题讨论】:

  • 您可能需要在客户端包含 x-ms-blob-type 标头。我认为查询参数 (comp) 仅适用于阻止列表上传。我不确定这是否适用于容器级 URL。
  • 您能详细说明一下吗?我不太确定如何添加标题。我可能错了,但我认为 UploadFromStreamAsync 自己处理请求,我无权修改其标头。
  • Docs 您必须将其添加到客户端发出的请求中。正如我所说,我只知道这对于实际的 blob 是正确的。我不确定容器。
  • 您检查过返回的 SAS 吗?它有效吗?您也可以尝试添加SharedAccessBlobPermissions.List 看看是否有任何改变
  • 我认为除了像我提出的那样发出上传请求之外,我还没有其他方法可以检查 sas 密钥。如果还有什么我可以使用的,请告诉我。

标签: c# azure azure-storage azure-blob-storage


【解决方案1】:

我能够重现错误,这就是我修复它的方法:

您需要将 SAS 传递给 CloudBlobContainer 而不是 CloudBlockBlob。然后使用容器检索 blob 引用(您可能希望使用文件的 filename 属性):

var container = new CloudBlobContainer(thesaskey);
var blob = container.GetBlockBlobReference("<yourFileName>");
await blob.UploadFromFileAsync(@"YOURPATH")

注意有一个方便的方法UploadFromFileAsync可以使用


这是我用来测试它的控制台应用程序:

class Program
{
    static void Main(string[] args)
    {

        var connectionString = String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
            "<AccountName>",
            "<AccountKey>");
        var storageAccount = CloudStorageAccount.Parse(connectionString);
        var blobClient = storageAccount.CreateCloudBlobClient();


        var container = blobClient.GetContainerReference("sasimagecontainer");
        container.CreateIfNotExistsAsync().GetAwaiter().GetResult();

        var sasUri = GetContainerSasUri(container);


        var container2 = new CloudBlobContainer(new Uri(sasUri));
        var blob2 = container2.GetBlockBlobReference("blobCreatedViaSAS.txt");
        blob2.UploadFromFileAsync(@"D:\test.txt").GetAwaiter().GetResult();

    }

    private static string GetContainerSasUri(CloudBlobContainer container)
    {

        //Set the expiry time and permissions for the container.
        //In this case no start time is specified, so the shared access signature becomes valid immediately.
        SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
        sasConstraints.SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddHours(24);
        sasConstraints.Permissions = SharedAccessBlobPermissions.List | SharedAccessBlobPermissions.Write |
                                     SharedAccessBlobPermissions.Create |
                                     SharedAccessBlobPermissions.Add | SharedAccessBlobPermissions.Read;

        //Generate the shared access signature on the container, setting the constraints directly on the signature.
        var sasContainerToken = container.GetSharedAccessSignature(sasConstraints);

        //Return the URI string for the container, including the SAS token.
        return container.Uri + sasContainerToken;
    }
}

【讨论】:

  • 我不明白你的问题。如果您将文件上传到容器中,它就会变成一个 blob。
  • 抱歉,我弄混了一些东西。我删除了评论。
猜你喜欢
  • 1970-01-01
  • 2019-02-07
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2019-03-28
  • 2017-02-22
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多