Serving Static Content From Azure Storage: Getting The Permissions Right

If we’re going to serve files directly from Azure via HTTP, the very first thing we need to do is ensure the blobs in your container have public read access.

There are three kinds of read access we can apply to an Azure blob storage container:

  • Private container: Only account owners can access information about the container or its blobs.
  • Public container: All blobs in the container are readable by anyone, and the container’s metadata and properties are also readable.
  • Public blob: The blobs in the container are readable by anyone, but container metadata and properties remain hidden.

Think of Goldilocks: “Private container” is too cold; “public container” is too hot. “Public blob” is just right.

Note that this means you should not mix public and non-public blobs in the same container.

It is theoretically possible to prevent anonymous access to a blob in a public container, and vice-versa. To avoid bogging this down in arcana, I won’t get into that.

Suffice it to say: If you set a container to public blob access, all blobs in that container can be viewed publicly.

Set MIME types

Just as important as setting the container’s permissions to allow public access to blobs is setting the correct MIME types on your files.

When a web browser requests your files, it depends on the Content-Type HTTP header to help it determine how to handle the file.

If there’s no Content-Type header in your server response, the browser doesn’t know how to handle the file — and will probably prompt the user to download it, or download it automatically.

Obviously, for images, HTML, JSON and the like, that’s not what you want to have happen. But if you do apply the correct MIME types to your blobs, Azure will send them along in the response, ensuring that your files are visible.

Setting MIME types via code

We can set MIME types quite easily when uploading the file.

Fortunately, there’s a BlobProperties collection in the CloudBlockBlob class, and one of its members is ContentType.

We simply set the value of ContentType to be the correct MIME type for whatever it is you want to send.

For example, if I want to upload a JPEG file:

using Microsoft.WindowsAzure.Storage;
using System.IO;

var account = CloudStorageAccount.Parse("YourStorageConnectionString");
var client = account.CreateCloudBlobClient();
var container = client.GetContainerReference(GetAzureContainerByFileType(type));
var blob = container.GetBlockBlobReference("myphoto.jpg");

blob.Properties.ContentType = "image/jpeg";

using(var file = File.OpenRead(@"c://path/to/myphoto.jpg")) {
	blob.UploadFromStream(file);
}

This code as a GitHub Gist: https://gist.github.com/dougvdotcom/e852b6531ecada85fbdf8a8d6bbc6f5b

If you need to change the MIME type on a file already in Azure storage, call the SetProperties method:

using Microsoft.WindowsAzure.Storage;
using System.IO;

var account = CloudStorageAccount.Parse("YourStorageConnectionString");
var client = account.CreateCloudBlobClient();
var container = client.GetContainerReference(GetAzureContainerByFileType(type));
var blob = container.GetBlockBlobReference("myphoto.jpg");

blob.Properties.ContentType = "image/jpeg";

blob.SetProperties();

This code as a GitHub Gist: https://gist.github.com/dougvdotcom/f2d20d23b5556bf94f9aab34a87f1ddb

Updating MIME types via GUI

It’s also fairly easy to change MIME types using either Azure Storage Explorer 6 or CloudBerry Explorer.

In CloudBerry Explorer:

  • Single-click on the file you want to update.
  • Click Set HTTP Headers.
  • In the dialog that comes up, find the Content-Type entry and single-click to highlight it.
  • Click the Edit button.
  • In the dialog box that comes up, either select the MIME type you want from the pull-down menu or free-type the MIME type you want used.
  • Click OK to store your change.
  • Click OK again to save your changes.

In Storage Explorer 6:

  • Double-click on the file you want to update.
  • In the dialog that comes up, enter the correct MIME value in the Content-Type textbox.
  • Click Update Properties
  • Click the X in the upper right hand corner to complete the task.

This slideshow requires JavaScript.

Link to your files

With the correct container permissions and the right MIME types on your files, you’re ready to directly serve files from Azure storage.

All you need to know is the name of your storage account; the name of your container; and the file name you want to display. Concatenate them like this:

$"https://{AccountName}.blob.core.windows.net/{ContainerName}/{FileName}";

So your URL will look something like this: https://mtmeditorial.blob.core.windows.net/frontpages/PPH_20160823.jpg

Here are some examples: Thumbnails of the front pages of the three daily newspapers my employer publishes.

Morning Sentinel
Morning Sentinel
Kennebec Journal
Kennebec Journal
Press Herald
Press Herald

Azure Storage URLs are case-sensitive

One important note: Unlike in default IIS configurations, where case doesn’t matter, when serving files from Azure storage directly, blob and container names are case-sensitive.

So if I have a file at https://mtmeditorial.blob.core.windows.net/frontpages/PPH_20160823.jpg, the URLs https://mtmeditorial.blob.core.windows.net/FrontPages/PPH_20160823.jpg and https://mtmeditorial.blob.core.windows.net/frontpages/pph_20160823.jpg will both 404.

To the best of my knowledge, there is no way to override this behavior.

Next up: CORS rules.

Featured photo by BANITAtour via Pixabay, in the public domain.
Featured photo by BANITAtour via Pixabay, in the public domain.

Leave a Reply

  • Check out the Commenting Guidelines before commenting, please!
  • Want to share code? Please put it into a GitHub Gist, CodePen or pastebin and link to that in your comment.
  • Just have a line or two of markup? Wrap them in an appropriate SyntaxHighlighter Evolved shortcode for your programming language, please!