Snelbinder
Snelbinder

Reputation: 81

Azure Storage C# client returns 403 forbidden in MVC app but 200 in console app

I'm running into issues using the Azure Storage C# client inside my MVC app, both locally and inside an Azure App Service. I'm using the client as follows in both the console and MVC5 applications:

var account = CloudStorageAccount.Parse("connectionstring");
var client = account.CreateCloudBlobClient();
var container = client.GetContainerReference("containername");
var blob = container.GetBlockBlobReference("somefile");
var exists = blob.Exists();

I'm using the exact same values for all parameters. The Exists call works fine in the console app but returns an exception in the MVC5 application:

[WebException: The remote server returned an error: (403) Forbidden.]

After inspecting both requests produced by the client using Fiddler it shows the following requests/responses.

Console app request:

HEAD <url> HTTP/1.1
User-Agent: Azure-Storage/8.3.0 (.NET CLR 4.0.30319.42000; Win32NT 6.2.9200.0)
x-ms-version: 2017-04-17
x-ms-client-request-id: 6d51e6c2-fb3f-48fd-ade5-2031d593b553
x-ms-date: Thu, 10 Aug 2017 07:35:52 GMT
Authorization: SharedKey <creds>
Host: <host>
Connection: Keep-Alive

Console app response:

HTTP/1.1 200 OK
Content-Length: 3992
Content-Type: image/gif
Content-MD5: Ehfh+rzNrbvTgIEh9gQgfw==
Last-Modified: Tue, 27 Jun 2017 13:48:41 GMT
Accept-Ranges: bytes
ETag: "0x8D4BD6338BAED01"
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: d7b7e17e-0001-003e-7bab-11987d000000
x-ms-version: 2017-04-17
x-ms-lease-status: unlocked
x-ms-lease-state: available
x-ms-blob-type: BlockBlob
x-ms-server-encrypted: false
Date: Thu, 10 Aug 2017 07:35:51 GMT

MVC5 request:

HEAD <url> HTTP/1.1
User-Agent: Azure-Storage/8.3.0 (.NET CLR 4.0.30319.42000; Win32NT 10.0.15063.0)
x-ms-version: 2017-04-17
x-ms-client-request-id: 138d3edc-a3b1-48c6-b268-6b878a4c01fd
x-ms-date: Thu, 10 Aug 2017 07:33:46 GMT
Authorization: SharedKey <creds>
Host: <host>
x-ms-request-root-id: ef1cb29-49a22f2b3f72be30
x-ms-request-id: |ef1cb29-49a22f2b3f72be30.
Request-Id: |ef1cb29-49a22f2b3f72be30.

MVC5 response:

HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
Transfer-Encoding: chunked
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: 106917c2-0001-00b8-2aaa-11ccaf000000
Date: Thu, 10 Aug 2017 07:33:45 GMT

Both applications are targeting .NET 4.5.2 and are using version 8.3.0 of the WindowsAzure.Storage package. I also tried version 8.2.1 and 6.2.1 but ran into the same problem.

Why would these two applications produce different HEAD requests when the code and values are exactly the same?

Upvotes: 3

Views: 1158

Answers (2)

MartijnBrands
MartijnBrands

Reputation: 91

Hello we had the same problem. Get always 403. After debugging for days I found that application insights added headers for the outgoing requests (because we track dependencies) to BLOB storage. Therefore the computed signature is not the same as the one in the request. When I compare ApplicationInsights.config from environments where we don't have problems I see that we missed this part

<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector">
  <ExcludeComponentCorrelationHttpHeadersOnDomains>
    <!-- 
    Requests to the following hostnames will not be modified by adding correlation headers. 
    This is only applicable if Profiler is installed via either StatusMonitor or Azure Extension.
    Add entries here to exclude additional hostnames.
    NOTE: this configuration will be lost upon NuGet upgrade.
    -->
    <Add>core.windows.net</Add>
    <Add>core.chinacloudapi.cn</Add>
    <Add>core.cloudapi.de</Add>
    <Add>core.usgovcloudapi.net</Add>
    <Add>localhost</Add>
    <Add>127.0.0.1</Add>
  </ExcludeComponentCorrelationHttpHeadersOnDomains>
</Add>

you see core.windows.net is excluded now, after this all worked fine.

Upvotes: 2

Snelbinder
Snelbinder

Reputation: 81

It turns out I'm running into this issue. In my MVC application I'm using Application Insights. In my web.config I have the following configuration, as suggested by the default AI template:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <remove name="ApplicationInsightsWebTracking" />
    <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
  </modules>
<system.webServer>

After disabling this web tracking module the x-ms-request-root-id, x-ms-request-id and Request-Id are no longer passed in the requests to Blob Storage and it works just fine.

Upvotes: 4

Related Questions