我已经阅读了几篇关于类似查询的帖子,比如this one,但我一直得到403。
最初我在Visual Studio中编写代码 - 访问存储blob的azure函数 - 一切运行正常。但是当我部署相同的功能时,它会抛出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运行时访问云上的存储(而不是模拟器)时能够完美运行,但是当在门户上部署或运行时,它无法运行。
我在这里错过了什么?
由于您排除了许多可能的原因,我可以重现您的问题的唯一方法是在存储帐户上配置防火墙。
本地代码可以正常工作,因为您可能已将本地IP添加到白名单中,而省略了此功能。在门户网站上,转到平台功能下的资源管理器。搜索outboundIpAddresses
并将这些(通常是四个)IP添加到存储帐户白名单中。
如果您添加了功能IP但仍然出现403错误,请检查存储和功能应用程序的位置。如果他们住在同一地区(就像在美国中部一样),两个人在没有通过outboundIpAddresses
的情况下以内部方式进行交流。我可以提供的解决方法是在计划中需要防火墙时在不同区域创建存储。否则只允许所有网络存储。