Ошибка 403 в производстве от WindowsAzure.Storage

У меня есть приложение WebForms, в котором используется WindowsAzure.Storage API v3. Он отлично работает в разработке и в одной рабочей среде, но я запускаю новый экземпляр, и любой код, который вызывает Azure Blob Storage, дает мне ошибку 403.

Я некоторое время играл с этим, и он не справляется с вызовом Blob Storage, поэтому вместо того, чтобы показывать мой код, я покажу свою трассировку стека:

[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 Storage получал 403. Он делает.
  • В отчаянии Installed Azure Powershell на сервере просто для проверки того, что какой-то тип связи с Azure работает. И это сработало хорошо.
  • Также просматривается портал управления azure, и это отлично работает.

Любые идеи? Это должен быть только порт 80 или 443, верно? Поэтому не должно быть никаких проблем с сетью. Сообщите мне, если это неправильно.

  • Рабочий производственный станок - это Azure VM (Server 2008 R2 с IIS 7.5) Существуют также некоторые различия с сервером:
  • Эта новая машина представляет собой физическое оборудование (Server 2012 и IIS 8).
  • Это IS использует другую учетную запись в моей подписке на лазурную печать, однако я пробовал в общей сложности 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

... Контейнеры - это просто перечисление имен контейнеров (их несколько):

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

... Да, у них есть символы верхнего регистра, что вызывает проблемы. Все будет зависеть от нижнего регистра, прежде чем он погаснет.

Также я убедился, что корректная AzureConnectionString выходит из моего класса настроек. Опять же, я попробовал несколько, которые работают в другом месте. И это работает и в других местах!

Ответ 1

Пожалуйста, проверьте часы на соответствующих серверах. Помимо неправильного ключа учетной записи, вы также можете получить ошибку 403, если время на сервере не синхронизируется с временем на серверах хранения (разрешить или убрать отклонение +/- 15 минут).

Ответ 2

Я также столкнулся с этой ошибкой. Моя проблема заключалась в том, что я включил динамические ограничения безопасности IP в моем web.config, а количество файлов, загружаемых в некоторых случаях (например, со страницами с большим количеством изображений), превышало максимальные пороговые значения, определенные мной в моем web.config.