Azure storage CORS returns origin wildcard and fai

2019-06-02 01:42发布

问题:

When enabling CORS on Azure blob storage, almost everything can be set but the "...Allow-Credentials" header, which is always true.

So when using a wildcard for the origin-header, the pre-flight request works fine and converts the wildcard into the actual origin.

But the subsequent GET request does not convert the wildcard and returns the following combination:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

which is illegal in Chrome (and probably other browsers, too). The error is

XMLHttpRequest cannot load ...
A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true.
Origin 'http://localhost' is therefore not allowed access. 

In the new WebAPI v2 CORS package wildcards are replaced with the actual origin. Also, why would I need credentials such as cookies in a request to the blob storage? Better turn it off.

How could I fix that when I want to use the origin wildcard?

UPDATE

Here's the initialize code I run on App_Start

public static void Initialize()
{
    // Azure blob storage settings
    var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString);
    var client = storageAccount.CreateCloudBlobClient();
    var serviceProperties = client.GetServiceProperties();
    serviceProperties.Cors = new CorsProperties();

    serviceProperties.Cors.CorsRules.Add(new CorsRule()
    {
        AllowedHeaders = new List<string>() { "*" },
        AllowedOrigins = new List<string>() { "*" },
        AllowedMethods = CorsHttpMethods.Get,
        ExposedHeaders = new List<string>() { "*" },
        MaxAgeInSeconds = 3600
    });

    client.SetServiceProperties(serviceProperties);
}

回答1:

The error that you encountered is due to setting withCredentials property on the xmlhttpreqeust to true ,in that case the browser will reject wildcard Access-Control-Allow-Origin.

In the new WebAPI v2 CORS package wildcards are replaced with the actual origin.

Returning wildcard is the right thing to enable caching, take a look at the following scenario:

  • User A sends GET request to a public blob on MAS (Microsoft Azure Storage).
  • If you are using a CDN/Proxy to cache public resources which is a best practice then the CDN will cache the blob with Access-Control-Allow-Origin set to '*'.
  • Now User B sends the same request to MAS and gets the response from the cache instead, in that case since the cached blob has wildcard Access-Control-Allow-Origin the browser will allow that request and you don't need to hit MAS servers.

Now in the other case that you always return the actual origin, you can't cache that resources for multiple clients since the browser will fail the CORS request if the Access-Control-Allow-Origin has an actual origin that differs from request origin header.

Also, why would I need credentials such as cookies in a request to the blob storage? Better turn it off.

You would need the credentials since one way to send authenticated requests is using the Authorization header, if the preflight request doesn't allow that then the browser should fail actual requests with Authorization header.



回答2:

It actually does work when

withCredentials == false

on the XmlHttpRequest object. In my case this setting got messed up in the js framework I'm using.