Azure Storage CORS Concepts - CORS Rules Concepts - Part Six

Welcome back to CORS Rules Concepts in Azure storage, In the previous article, we saw how the CORS rule is represented and explained one by one detailly with demos. Here we see the remaining CORS rules with the following demos. Please read the previous parts of the series before continuing with this one,
Allowed Headers
  1. <AllowedHeaders>  
  2.    x-ms-meta-*, x-api-key  
  3. </AllowedHeaders>   
AllowedHeaders list the custom headers that the incoming request may send. This can be a list of header names that either are exact matches, also called literals headers, or they can also be wildcard prefixed headers. For example, the snippet allows any headers that start with x-ms-meta-, and it also allows the literals x-api-key header. The value can also be a single wildcard value to allow any header. Keep in mind the limits that we talked about in the last module regarding how may prefix headers you can have.
In the portal, I’ve set a literal header value for the AllowHeaders property set to x-api-key. Let’s look at the basic CORS image demo.
Now in this example, remember that I’ve set the cross-origin attribute, so this will result in a CORS request. Would you expect the request to fail or succeed now that I’ve only allowed a specific header?
Well, let’s find out. And it succeeds. The reason is we did not initiate the request with any headers, so the outgoing request did not specify an Access-Control-Request-Headers header for Azure to evaluate.
Exposed Headers
  1. <ExposedHeaders>  
  2.    x-ms-meta-* , x-request-duration  
  3. </ExposedHeaders>   
The ExposedHeaders property allows you to specify what additional headers Azure will tell the browser to expose on the request. Azure will include the Access-Control-Expose-Headers response header to indicate to the browser what HTTP header is allowed to be exposed. The value can be a comma-separated list of literal or wildcard prefixed headers.
If you want to provide unrestricted access to all response headers Azure sends on responses, you could enter a single wildcard value, but I wouldn’t really recommend this. It means that any client that initiates a CORS request can read any header sent back from Azure, which could include sensitive information that could be used in malicious ways.
In general, it’s best to only allow specific headers as needed. In this example, if a CORS request came in the response Azure sends back would tell the browser that the request initiator could access any header starting with x-ms-meta-, or the literal x-request-duration header. Even if Azure sent back other headers, they would not be visible to the initiator.
I’m using that phrase “visible to the initiator” specifically because all response headers are always visible to you as a user using browser tools or by inspecting the raw HTTP response. This mechanism is only to restrict what an indicator, like a script, can access. In other words, this does not hide any response headers from the server, its just hints to the browser to restrict exposing headers to scripts or resources on the page.
In the portal, I’m now set to expose only the x-ms-request-id header, which is present on all storage requests.
Let’s open the network tool and run the demo. The request succeeded, we hoped, but what do we expect to see in the response headers for our image request if we’ve set ExposedHeaders to be a single literal value? Well, let’s peek. And do you see that x-ms-request-id coming back?
Max Age In Seconds
  1. <MaxAgeInSeconds>  
  2.    180  
  3. </ MaxAgeInSeconds>   
MaxAgeInSeconds property indicates to the browser the amount of time to cache a pre-flight options request-response. During that time frame, if another CORS request would have initiated the same pre-flight request, the browser just skips the pre-flight request since it already understands what the response will be. This value is exposed by Azure automatically via the previously mentioned Access-control-Max-Age response header, which the browser can look for.
For Azure Storage scenarios, this is a good practice to set as it will reduce the amount of pre-flight requests you’ll be billed for. Keep in mind, though, that providing a value that is too high may result in browser caching and old CORS response. A good way to think about this is that after you make a change in Azure to your CORS rule, it will take up to this many seconds to propagate to any previous browsers that requested content. In this example, the browser will cache pre-flight responses for 3 minutes. This means, at most, a client browser maybe 3 minutes out of Sync with any changes you make to your CORS rules configuration.
Back in the portal, I’ve set a max-age of 30 seconds for our CORS rule. It’s also important to not confuse the max-age rule for CORS with HTTP caching rules, they are not the same. Max-age in CORS only applies to pre-flight requests.
Normal HTTP caching rules can still take effect on the actual resource requests. The request for the image we’re all served from the browser cache because the browser cached the image from my first demos, and then did not fetch a new image from the server since I enabled browser caching.
That’s it -- I hope you have learned how to create CORS rules for Azure Storage using AllowedOrigins, AllowedMethods, AllowedHeaders, ExposedHeaders, and MaxAgeInSeconds properties. Feel free to fill up the comment box below if you need any further assistance.