Azure Function v1 禁止访问云中的存储队列
Azure Function v1 access forbidden to Storage Queue within the Cloud
我有一个 Azure Function v1,SDK 1.0.24 试图访问我的存储队列,它在本地运行良好,我可以看到正确存储的消息。但是,一旦我将它发布到云中,它就会失败并显示 403 禁止,我 运行 没有线索。
我检查了几次连接字符串,我检查了请求和响应中的时间戳,完全没问题。我尝试更新了几个 NuGet 包,但最后为什么在它们损坏时应该在本地工作而不是在线?我没有使用 Application Insights。在主机日志中我发现了这个错误:
2019-01-16T12:38:32.460 [Verbose] Host
'44bf8a95b6652eed85464155b2b48df2' failed to acquire host lock lease:
Microsoft.WindowsAzure.Storage: The remote server returned an error:
(403) Forbidden.
我怀疑 Azure 中有一个与安全相关的设置阻止了访问(但我对安全功能没有任何控制权,管理员也不知道阻止问题可能是什么)。
问题出在 QueueTrigger 上,因此我制作了一个具有替代访问权限的小函数来重现该问题:
public static class TestStorageQueue
{
[FunctionName("TestStorageQueue")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req,
TraceWriter log)
{
log.Info("START");
try
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
log.Info(ConfigurationManager.ConnectionStrings["soastorage"]?.ConnectionString);
CloudStorageAccount storeAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["soastorage"]?.ConnectionString);
CloudQueueClient queueClient = storeAccount.CreateCloudQueueClient();
CloudQueue queue = queueClient.GetQueueReference("myqueue");
log.Info("trying to get message from queue");
var cloudMessage = queue.GetMessage(); // 403 happens here
log.Info("received message item");
var message = cloudMessage?.AsBytes;
var length = message?.Length ?? 0;
response.Content = new StringContent("received message length: " + length.ToString());
return response;
}
catch(Exception ex)
{
var response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
response.Content = new StringContent(ex.Message);
return response;
}
}
}
更新
很有趣,搜索了2天的答案,我一发布,我们就找到了原因。问题是 Azure 存储防火墙,即使将所有 MS 服务列入白名单,它仍然会阻止它们。所以临时解决办法是关掉它,这不是真正的解决办法,所以问题仍然悬而未决
尝试使用 Function app outbound IPs 配置存储防火墙,结论:
在 Azure 门户的功能面板上,平台功能 > 资源浏览器。
找到 outboundIpAddresses
并将它们全部添加到防火墙 IP 列表。
如果我们的功能在专用应用服务计划(如基本、标准等)上,如果我们想将计划扩展到其他定价层,请添加 possibleOutboundIPAddresses
。
如果我们的函数在消费计划中,我们可能必须将函数应用程序的数据中心列入白名单。
我有一个 Azure Function v1,SDK 1.0.24 试图访问我的存储队列,它在本地运行良好,我可以看到正确存储的消息。但是,一旦我将它发布到云中,它就会失败并显示 403 禁止,我 运行 没有线索。
我检查了几次连接字符串,我检查了请求和响应中的时间戳,完全没问题。我尝试更新了几个 NuGet 包,但最后为什么在它们损坏时应该在本地工作而不是在线?我没有使用 Application Insights。在主机日志中我发现了这个错误:
2019-01-16T12:38:32.460 [Verbose] Host '44bf8a95b6652eed85464155b2b48df2' failed to acquire host lock lease: Microsoft.WindowsAzure.Storage: The remote server returned an error: (403) Forbidden.
我怀疑 Azure 中有一个与安全相关的设置阻止了访问(但我对安全功能没有任何控制权,管理员也不知道阻止问题可能是什么)。
问题出在 QueueTrigger 上,因此我制作了一个具有替代访问权限的小函数来重现该问题:
public static class TestStorageQueue
{
[FunctionName("TestStorageQueue")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req,
TraceWriter log)
{
log.Info("START");
try
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
log.Info(ConfigurationManager.ConnectionStrings["soastorage"]?.ConnectionString);
CloudStorageAccount storeAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["soastorage"]?.ConnectionString);
CloudQueueClient queueClient = storeAccount.CreateCloudQueueClient();
CloudQueue queue = queueClient.GetQueueReference("myqueue");
log.Info("trying to get message from queue");
var cloudMessage = queue.GetMessage(); // 403 happens here
log.Info("received message item");
var message = cloudMessage?.AsBytes;
var length = message?.Length ?? 0;
response.Content = new StringContent("received message length: " + length.ToString());
return response;
}
catch(Exception ex)
{
var response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
response.Content = new StringContent(ex.Message);
return response;
}
}
}
更新 很有趣,搜索了2天的答案,我一发布,我们就找到了原因。问题是 Azure 存储防火墙,即使将所有 MS 服务列入白名单,它仍然会阻止它们。所以临时解决办法是关掉它,这不是真正的解决办法,所以问题仍然悬而未决
尝试使用 Function app outbound IPs 配置存储防火墙,结论:
在 Azure 门户的功能面板上,平台功能 > 资源浏览器。
找到
outboundIpAddresses
并将它们全部添加到防火墙 IP 列表。如果我们的功能在专用应用服务计划(如基本、标准等)上,如果我们想将计划扩展到其他定价层,请添加
possibleOutboundIPAddresses
。如果我们的函数在消费计划中,我们可能必须将函数应用程序的数据中心列入白名单。