Gaurav Mantri's Personal Blog.

Avoiding “AuthorizationFailed” error when hand-crafting Shared Access Signature for Azure Storage

I’ve been quite active on Stack Overflow answering a lot of Azure related questions (mostly around Azure Storage). One thing I noticed there is that there are a lot of folks running into issues when they’re trying to write code themselves for creating Shared Access Signature. Most of the errors they get are around “AuthorizationFailed” error with a variety of error codes.

In this post we’re going to talk about how you can avoid these errors. So let’s start!

Use SDK!

Three words: People, Use SDK!

When you’re trying to hand-craft the Shared Access Signature (SAS), essentially you’re reinventing the wheel and there’s absolutely no need to do so. I mean it, seriously!

Storage team has done an extremely great job of creating SDKs for most commonly used languages including .Net, Java, Node, Python, PHP, and lot more.

Please use them, I implore you :). They are super easy to use and you don’t really have to understand how to create SAS tokens.

Using SDK is a real time saver.


But then, I forget that we as developers derive pleasure by doing things on our own :P. So for those, who still are willing to go ahead and hand craft those SAS tokens, please read along.

So, in my experience answering questions related to various errors on Stack Overflow related to SAS token creations, I observed some common mistakes.

Next, I would like to talk about those and how can we avoid making them.

Read The Documentation!

One thing I really liked about Azure Storage Team is how great job they have done with the documentation. I’m not exaggerating when I say that it is one of best documented sites in Azure.

The team has provided detailed explanation of how you would go about creating SAS token and I would strongly encourage you to read the documentation carefully and follow it to a T.

You can find the documentation here:

Account SAS: https://docs.microsoft.com/en-us/rest/api/storageservices/create-account-sas

Service SAS: https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas

Understand Error Message

Whenever you access a SAS URL (say in a browser) and it fails, Azure Storage provides a detailed error message something similar to below:

<?xml version="1.0" encoding="utf-8"?>
    <Error>
        <Code>
            AuthenticationFailed
        </Code>
        <Message>
            Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
            RequestId:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
            Time:2020-02-19T13:53:58.2315262Z
        </Message>
        <AuthenticationErrorDetail>Signature did not match. String to sign used was r
            2020-02-18T00:00:00Z
            2020-02-25T00:00:00Z
            /blob/account/container/blob



            2015-04-05

            


            
        </AuthenticationErrorDetail>
    </Error>

Please pay special attention to the error message as it contains important details about why the SAS request failed. Use this information to go back and look at your code.

Storage team has also published a list of SAS error codes and I strongly recommend that you take a look at them to find out why your SAS is failing.

You can find this list here: https://docs.microsoft.com/en-us/rest/api/storageservices/sas-error-codes

Base64 Decode Storage Key

Storage account key is a base64 encoded string and in order to compute signature, we have to convert that into byte array. One of the most common mistakes I have seen is that folks treat storage key as a regular string and convert that into byte array using UTF8 or any other encoding.

Assuming you’re using C#, the correct way to get byte array would be:

var storageKeyBytes = Convert.FromBase64String(storageKey);

Pay Special Attention to “StringToSign” formatting

The way you create a SAS Token is that you create a StringToSign and sign this with your account key to get a signature. This signature gets included in your SAS URL and Storage Service uses the query parameters in your SAS URL to create it’s own signature and compares it with the signature you created.

Only when the two values match, SAS request gets processed successfully.

Most of the errors I encountered are related to improperly formatted this StringToSign. So please special attention to it.

Furthermore, the format of this StringToSign varies by Storage Service REST API version so please pay special attention to the format of this.

For example, here’s the format if you’re trying to create a SAS Token for a Blob Service resource using REST API version between 2015-04-05 and 2018-03-28.

StringToSign = signedpermissions + "\n" +       //Permissions in SAS e.g. read, write, list etc.
               signedstart + "\n" +             //Date/time in UTC when SAS token becomes effective.
               signedexpiry + "\n" +            //Date/time in UTC when SAS token expires.
               canonicalizedresource + "\n" +   //Canonical resource.
               signedidentifier + "\n" +        //Signed identifier when a SAS token is created using a shared access policy.
               signedIP + "\n" +                //IP address or range from where a SAS URL can be used.
               signedProtocol + "\n" +          //HTTPS or HTTP/HTTPS
               signedversion + "\n" +           //REST API Version
               rscc + "\n" +                    //Cache-Control override header
               rscd + "\n" +                    //Content-Disposition override header 
               rsce + "\n" +                    //Content-Encoding override header
               rscl + "\n" +                    //Content-Language override header
               rsct                             //Content-Type override header

Any slight deviation from this format will result in a Signature did not match error (an example of it I have included above). Again, please look at the error details to find out the discrepancy.

Also, if you’re not using a parameter in your SAS URL (say cache-control), please make sure to use empty string for that.

Construct Query String Appropriately

Once you have the SAS Token, please make sure that you’re constructing the query string appropriately.

Again, follow the documentation to a “T” to create your SAS Query String.

Don’t Forget To URL Encode Your Query Parameters

It’s important to URL encode your query parameters. This becomes really important for “sig” query string parameter as it might contain some characters like “/” and “=” which if not escaped via URL encoding will result in your SAS URL failure.

Summary

That’s it for this post! I hope you have found this post useful. If you find any issues with the post, please let me know and I will get it fixed ASAP.

Happy Coding!

Azure Cosmos DB and Node SDK – Part III: Working with Documents

In the previous posts in this series, we saw how you can work with databases and containers in Cosmos DB using their Node SDK. You can read those posts here: Part I: Working with databases: … [Continue reading]

Cosmos DB and Node SDK – Part II: Working with Containers

In the previous post, we saw how we can use Node SDK for Cosmos DB to work with databases. You can read that post here: https://gauravmantri.com/2019/06/04/cosmos-db-and-node-sdk-working-with-databases/. In this post, we will see how we can manage … [Continue reading]

Cosmos DB and Node SDK – Part I: Working with Databases

It has been a while that I wrote something :). There have been so many things I learnt in last few years and I wanted to share my learnings but one thing or other kept me away. I am hoping that I will be break this and post regularly going … [Continue reading]

Attitude Matters (When It Comes To Winning Users Over)!

Earlier this month we deprecated our flagship product (Azure Management Studio) and replaced that with a brand-new product (Cerulean). You can read more about the deprecation on our website at … [Continue reading]

Oops! I Deleted My Blobs! What Can I Do?

Honestly, Nothing! But that’s before reading this post. After reading this post, you don’t have to worry about a thing. In this post we will talk about Soft Delete functionality recently announced by Azure Storage. This super cool functionality will … [Continue reading]

Zone Redundant Storage (Preview v/s Classic)–Compared & Contrasted

Recently I ran into this blog post by Azure Storage Team: Azure Zone Redundant Storage in public preview. When I saw this post, the first thought that came to my mind was “it must surely be a mistake” , after all Zone Redundant Storage (ZRS) has been … [Continue reading]

Understanding Azure Storage Blob Access Tiers

It has been really-really long time that I have written a blog post. Past year or so has been simply crazy. From acquiring Cerebrata back to building a brand new product (Cerulean) from scratch, things kept me quite busy. In this blog post we will … [Continue reading]

My Thoughts On Current Euphoria Over Startups In India

Nowadays everyone wants to do a startup. There is a general feeling that if they are not doing a startup, they are not doing anything . I was listening to an old song by Amitabh Bachchan and took the liberty of modifying it to reflect the current … [Continue reading]

Azure Storage – Shared Access Signature Enhancements

Over the past few months, Azure Storage Team released two major upgrades. Both of these upgrades involve some really interesting new features and improvements. Among these new features and improvements include changes to Shared Access Signature (SAS) … [Continue reading]