【问题标题】:Azure blob returns 403 forbidden from Azure function running on portalAzure Blob 返回 403 禁止在门户上运行的 Azure 函数
【发布时间】:2019-02-07 01:48:21
【问题描述】:

我已经阅读了几篇关于类似查询的帖子,例如 this one,但我一直收到 403。

最初我在 Visual Studio 中编写代码 - 访问存储 blob 的天蓝色函数 - 一切运行良好。但是当我部署相同的功能时,它会抛出 403!我尝试了建议,迁移到 x64 等并删除其他文件,但没有任何效果。

请注意 - 我已多次验证 - 访问密钥正确且有效

所以,我做了以下所有事情

(1) - 我在 Portal 本身上编写了一个简单的 Azure 函数(以排除部署怪癖),瞧,同样的 403!

var storageConnection = "DefaultEndpointsProtocol=https;AccountName=[name];AccountKey=[key1];EndpointSuffix=core.windows.net";
var cloudStorageAccount = CloudStorageAccount.Parse(storageConnection);
var blobClient = cloudStorageAccount.CreateCloudBlobClient();

var sourceContainer = blobClient.GetContainerReference("landing");
CloudBlockBlob blob = container.GetBlockBlobReference("a.xlsx");

using (var inputStream = new MemoryStream())
{
    log.Info($"Current DateTime: {DateTime.Now}");
    log.Info("Starting download of blob...");
    blob.DownloadToStream(inputStream); // <--- 403 thrown here!!
    log.Info("Download Complete!");
}

(2) - 我通过记录日期时间和函数服务器上的 UTC 验证了日期时间

(3) - 我使用了在门户网站上生成的 Account SAS 密钥,但仍然给出 403。我在 SAS 密钥生成后等待了超过 30 秒,以确保 SAS 密钥传播。

var sasUri = "https://[storageAccount].blob.core.windows.net/?sv=2017-11-09&ss=b&srt=sco&sp=rwdlac&se=2019-07-31T13:08:46Z&st=2018-09-01T03:08:46Z&spr=https&sig=Hm6pA7bNEe8zjqVelis2y842rY%2BGZg5CV4KLn288rCg%3D";
StorageCredentials accountSAS = new StorageCredentials(sasUri);
var cloudStorageAccount = new CloudStorageAccount(accountSAS, "[storageAccount]", endpointSuffix: null, useHttps: true);

// rest of the code same as (1)

(4) - 我在代码中即时生成了 SAS 密钥,但又是 403。

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";
}

并将上述用作

var sourceContainer = blobClient.GetContainerReference("landing");
var sasKey = GetContainerSasUri(sourceContainer);
var container = new CloudBlobContainer(new Uri(sasKey));

CloudBlockBlob blob = container.GetBlockBlobReference("a.xlsx"); 

我完全不明白为什么代码在从 Visual Studio 运行、访问云上的存储(而不是模拟器)时可以完美运行,但是当在门户上部署或显式运行相同的代码时,它无法运行。

我在这里错过了什么?

【问题讨论】:

  • 您是否尝试过使用绑定而不是自己访问 blob?你的函数是如何触发的?
  • @Kamo - 我的函数目前正在使用 Postman 或门户本身进行调用/测试,但最终将通过数据工厂触发
  • 您能否提供完整的异常和堆栈跟踪?

标签: azure azure-functions azure-blob-storage


【解决方案1】:

由于您已经排除了许多可能的原因,我可以重现您的问题的唯一方法是在存储帐户上配置防火墙。

在本地代码可以正常工作,因为您可能已将本地 IP 添加到白名单中,而函数省略了此步骤。在门户上,转到平台功能下的资源浏览器。搜索 outboundIpAddresses 并将这些(通常是四个)IP 添加到存储帐户白名单中。

如果您添加了 Function IP 但仍然出现 403 错误,请检查 Storage 和 Function 应用的位置。如果他们住在同一个地区(比如都在美国中部),那么两个人以内部方式进行通信,而不通过outboundIpAddresses。如果您的计划中需要防火墙,我可以提供的解决方法是在不同的区域创建一个存储。否则只允许所有网络存储。

【讨论】:

  • 是的,问题是因为在存储上设置了防火墙。禁用它,它现在工作正常。
猜你喜欢
  • 2014-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 2017-11-07
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多