Ошибка 403 в производстве из WindowsAzure.Storage
У меня есть приложение WebForms, которое использует WindowsAzure.Storage API v3. Он отлично работает в разработке и в одной производственной среде, но я запускаю новый экземпляр, и любой код, который вызывает хранилище BLOB-объектов Azure, выдает ошибку 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 здесьВ некоторых старых версиях API REST (которые я не использую напрямую) возникла проблема с отметками времени, поэтому я убедился, что время правильное, и даже попытался переключить сервер на время UTC.Попытался переключить строку подключения между http / https.Обновлен до последней версии API (v3.1)Пробовал поиграться с кодом, чтобы каждый вызов в хранилище Azure получал 403. Это так.В отчаянии установил Azure Powershell на сервере, чтобы убедиться, что какой-то тип связи с Azure работает. И это работало нормально.Перейдите на портал управления лазурью, и это прекрасно работает.Есть идеи? Это просто порт 80 или 443, верно? Так что не должно быть никаких проблем с сетью. Дайте мне знать, если это не так.
Работающая рабочая машина - это виртуальная машина Azure (Server 2008 R2 с IIS 7.5). Есть также некоторые различия с сервером:Этот новый компьютер является физическим оборудованием (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
...Контейнеры это просто перечисление имен контейнеров (их несколько):
Public Enum Containers
CallerWavs
CampaignImports
Delve
Exports
CampaignImages
Logos
ReportLogos
WebLinkImages
End Enum
... Да, они имеют заглавные буквы, что вызывает проблемы. Все заставлено в нижнем регистре, прежде чем он выходит.
Также я проверил, что правильный класс AzureConnectionString выходит из моего класса настроек. Опять же, я попробовал несколько, которые работают в другом месте. И этот работает в другом месте также!