来自 WindowsAzure.Storage 的生产中出现 403 错误

Posted

技术标签:

【中文标题】来自 WindowsAzure.Storage 的生产中出现 403 错误【英文标题】:403 error in production from WindowsAzure.Storage 【发布时间】:2014-05-14 17:30:31 【问题描述】:

我有一个使用 WindowsAzure.Storage API v3 的 WebForms 应用程序。它在开发和一个生产环境中运行良好,但我正在推出一个新实例,任何调用 Azure Blob 存储的代码都会给我一个 403 错误。

我一直在摆弄这个,它在任何调用 Blob 存储时都失败了,所以我不会显示我的代码,而是显示我的堆栈跟踪:

[WebException: The remote server returned an error: (403) Forbidden.]
   System.Net.HttpWebRequest.GetResponse() +8525404
   Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) +1541

[StorageException: The remote server returned an error: (403) Forbidden.]
   Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) +2996
   Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.CreateIfNotExists(BlobContainerPublicAccessType accessType, BlobRequestOptions requestOptions, OperationContext operationContext) +177
   ObsidianData.Azure.Storage.GetContainer(CloudBlobClient client, Containers targetContainer) in D:\Dev\nSource\Obsidian\Source\ObsidianData\Azure\Storage.vb:84
   ObsidianWeb.Leads.HandleListenLink(String fileName, HyperLink link) in D:\Dev\nSource\Obsidian\Source\ObsidianWeb\Bdc\Leads.aspx.vb:188
   ObsidianWeb.Leads.LoadEntity_ContactDetails(BoLead lead) in D:\Dev\nSource\Obsidian\Source\ObsidianWeb\Bdc\Leads.aspx.vb:147
   ObsidianWeb.Leads.LoadEntity(BoLead Lead) in D:\Dev\nSource\Obsidian\Source\ObsidianWeb\Bdc\Leads.aspx.vb:62
   EntityPages.EntityPage`1.LoadEntity() +91
   EntityPages.EntityPage`1.Page_LoadComplete(Object sender, EventArgs e) +151
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4018

这是我尝试过的...

在此环境中失败的 AzureStorageConnectionString 在生产中肯定有效 其他连接字符串(来自其他有效的生产环境)也在这里得到 403 在一些旧版本的 REST api 中似乎存在时间戳问题(我没有直接使用...),所以我确定时间是正确的,甚至尝试将服务器切换到 UTC 时间。李> 尝试切换 http/https 之间的连接字符串。 升级到最新版本的 API (v3.1) 尝试修改代码以确保对 Azure 存储的每次调用都得到 403。确实如此。 无奈之下,在服务器上安装了 Azure Powershell 只是为了验证与 Azure 的某种类型的通信是否正常。这很好用。 也浏览到了 azure 管理门户,并且工作正常。

有什么想法吗?这应该只是使用端口 80 或 443,对吧?所以这不应该是某种网络问题。让我知道这是否有误。

工作的生产机器是 Azure VM(带有 IIS 7.5 的 Server 2008 R2) 与服务器也有一些区别: 这台新机器是物理硬件(Server 2012 和 IIS 8) 这是在我的 azure 订阅中使用不同的存储帐户,但是我一共尝试了 3 个连接字符串,但它们都不能在这里工作。

更新:有人要求查看代码。好的,我写了一个名为 Azure.Storage 的类,它只是抽象了我的云存储代码。我们对 Storage.Exists 的调用失败了,所以这是该类中感觉相关的部分:

    Public Shared Function Exists(container As Containers, blobName As String) As Boolean
        Dim Dir As CloudBlobContainer = GetContainer(container)
        Dim Blob As CloudBlockBlob = Dir.GetBlockBlobReference(blobName.ToLower())

        Return Blob.Exists()
    End Function

    Private Shared Function GetContainer(client As CloudBlobClient, targetContainer As Containers)
        Dim Container As CloudBlobContainer = client.GetContainerReference(targetContainer.ToString.ToLower())
        Container.CreateIfNotExists()
        Container.SetPermissions(New BlobContainerPermissions() With .PublicAccess = BlobContainerPublicAccessType.Blob)

        Return Container
    End Function

    Private Shared Function GetCloudBlobClient() As CloudBlobClient
        Dim Account As CloudStorageAccount = CloudStorageAccount.Parse(Settings.Cloud.AzureStorageConnectionString())

        Return Account.CreateCloudBlobClient()
    End Function

...Containers 只是容器名称的枚举(有几个):

 Public Enum Containers
     CallerWavs
     CampaignImports
     Delve
     Exports
     CampaignImages
     Logos
     ReportLogos
     WebLinkImages
 End Enum

...是的,它们有大写字符,这会导致问题。在输出之前,所有内容都被强制小写。

我还验证了正确的 AzureConnectionString 来自我的设置类。再次,我尝试了一些其他地方的工作。这个也可以在其他地方使用!

【问题讨论】:

我不认为你可以发布你的代码吗? 请检查相关服务器上的时钟。如果服务器上的时间与存储服务器上的时间不同步(允许 +/- 15 分钟偏差),您也可能会收到 403 错误。 @GauravMantri 检查了,那在我包含在问题中的列表中,但是谢谢。 ;) 您可以尝试的另一件事是获取应该是 WebException 的 InnerException,阅读其响应流以查看有关错误的更多详细信息。 @GauravMantri 嗯,我会试试的。你认为这会提供比我在堆栈跟踪中得到的更多吗? 【参考方案1】:

请检查相关服务器上的时钟。除了不正确的帐号密钥外,如果服务器上的时间与存储服务器上的时间不同步,您也可能会收到 403 错误(允许存在 +/- 15 分钟偏差)。

【讨论】:

原来是这样,我至少检查了两次。也许这就是我凌晨 2 点工作的结果。顺便说一句,我已经使用了你的 Cerebrata 技术,我很喜欢它,谢谢你:) 天啊,我快疯了。这太愚蠢了。为什么它应该返回 403 时差,为什么不至少提供一个有意义的消息,例如“您的请求时间不能被接受”。【参考方案2】:

我也遇到了这个错误。我的问题是我在 web.config 中打开了动态 IP 安全限制,并且在某些情况下(例如,带有大量图像的页面)下载的文件数量超过了我在 web.config 中定义的最大阈值。

【讨论】:

【参考方案3】:

在我的情况下,访问密钥与源代码使用的连接字符串不同。

因此请尝试重新检查您的 Azure -> [存储帐户名称] -> 访问密钥 -> key1 -> 密钥和连接字符串

【讨论】:

以上是关于来自 WindowsAzure.Storage 的生产中出现 403 错误的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft.WindowsAzure.Storage 与 Microsoft.WindowsAzure.StorageClient

如何用 Microsoft.Azure.Storage.Blob 替换 Microsoft.WindowsAzure.Storage

OperationContext 使用 (Microsoft.WindowsAzure.Storage)

Microsoft.Azure.Storage 和 WindowsAzure.Storage Nuget 包有啥区别?

Microsoft.WindowsAzure.Storage:找不到有效的帐户信息组合

如何使用 Microsoft.WindowsAzure.Storage.Table 的 TableOperators.Not 运算符