title: Azure REST API Create Container, .NET Client Profile, 403 Forbidden, The MAC signature found is not the same as any computed signature
body: <p>after reading all posts that come close to this, I still find no solution and after "fiddling" around for hours, here goes a post, in hopes that someone has an idea:</p>
  
  <p>The closest response I have found is 
  <a href="https://stackoverflow.com/questions/4612693/getting-403-forbidden-webexception-for-azure-blob-put-request">here</a></p>
  
  <p>but two things from these posts do not apply: 
  1. I'm using example code that certainly works in most cases.
  2. I do not have access to any Azure StorageClient simplifiers, since I am required to use the .NET client profile.
  3. It is probably a stupid error that I just don't see :-)</p>
  
  <p>Here is the call:</p>
  
  <pre><code>// Create Blob
  // using REST: http://msdn.microsoft.com/en-us/library/windowsazure/dd135733.aspx
  BlobHelper blobHelper = new BlobHelper(_storageAccountName, _storageKey);
  Console.WriteLine("Create container...");
  if (!blobHelper.CreateContainer("mytestcontainer")) //(blobInfo.ContainerName))
     {
       Console.WriteLine("REST: Create Blob Failed");
     }
  </code></pre>
  
  <p>And here is wire request (fiddler):</p>
  
  <pre><code>PUT /devstoreaccount1/mytestcontainer?restype=container HTTP/1.1
  x-ms-date: Mon, 25 Jun 2012 16:54:01 GMT
  x-ms-version: 2009-09-19
  Authorization: SharedKey devstoreaccount1:REpHdtTSQrwGtXuEbLJmRQdpe/j2l5icmGUeFkQ09jw=
  Host: 127.0.0.1:10000
  Content-Length: 0
  Connection: Keep-Alive
  </code></pre>
  
  <p>The same thing happens whether I use live Azure Storage or the Developer Storage.</p>
  
  <p>Here is the wire response:</p>
  
  <pre><code>HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
  Content-Length: 698
  Content-Type: application/xml
  Server: Microsoft-HTTPAPI/2.0
  x-ms-request-id: d5430ddc-f146-4102-b8db-a8bfab0ed82f
  Date: Mon, 25 Jun 2012 16:54:00 GMT
  
  &lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;Error&gt;&lt;Code&gt;AuthenticationFailed&lt;/Code&gt;&lt;Message&gt;Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
  RequestId:d5430ddc-f146-4102-b8db-a8bfab0ed82f
  Time:2012-06-25T16:54:01.3354093Z&lt;/Message&gt;&lt;AuthenticationErrorDetail&gt;The MAC signature found in the HTTP request 'REpHdtTSQrwGtXuEbLJmRQdpe/j2l5icmGUeFkQ09jw=' is not the same as any computed signature. Server used following string to sign: 'PUT
  
  
  0
  
  
  
  
  
  
  
  
  x-ms-date:Mon, 25 Jun 2012 16:54:01 GMT
  x-ms-version:2009-09-19
  /devstoreaccount1/devstoreaccount1/mytestcontainer
  restype:container'.&lt;/AuthenticationErrorDetail&gt;&lt;/Error&gt;
  </code></pre>
  
  <p>Needless to say, this driving me nuts, so any tips appreciated.</p>
  
  <p>The source code, which is directly from the Azure Storage <a href="http://azurestoragesamples.codeplex.com/releases/view/61325" rel="nofollow noreferrer">REST API sample</a>, RESTHelper.cs. This works in many scenarios, but not this one:</p>
  
  <pre><code>    #region REST HTTP Request Helper Methods
  
      // Construct and issue a REST request and return the response.
  
      public HttpWebRequest CreateRESTRequest(string method, string resource, string requestBody = null, SortedList&lt;string, string&gt; headers = null, 
          string ifMatch = "", string md5 = "")
      {
          byte[] byteArray = null;
          DateTime now = DateTime.UtcNow;
          string uri = Endpoint + resource;
  
          HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
          request.Method = method;
          request.ContentLength = 0;
          request.Headers.Add("x-ms-date", now.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
          request.Headers.Add("x-ms-version", "2009-09-19"); //2009-09-19, 2011-08-18
  
          if (IsTableStorage)
          {
              request.ContentType = "application/atom+xml";
  
              request.Headers.Add("DataServiceVersion", "1.0;NetFx");
              request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");
          }
  
          if (headers != null)
          {
              foreach (KeyValuePair&lt;string, string&gt; header in headers)
              {
                  request.Headers.Add(header.Key, header.Value);
              }
          }
  
          if (!String.IsNullOrEmpty(requestBody))
          {
              request.Headers.Add("Accept-Charset", "UTF-8");
  
              byteArray = Encoding.UTF8.GetBytes(requestBody);
              request.ContentLength = byteArray.Length;
          }
  
          request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, ifMatch, md5));
  
          if (!String.IsNullOrEmpty(requestBody))
          {
              request.GetRequestStream().Write(byteArray, 0, byteArray.Length);
          }
  
          return request;
      }
  
  
      // Generate an authorization header.
      //RHT: http://msdn.microsoft.com/en-us/library/dd179428.aspx
  
      public string AuthorizationHeader(string method, DateTime now, HttpWebRequest request, string ifMatch = "", string md5 = "")
      {
          string MessageSignature;
  
          if (IsTableStorage)
          {
              MessageSignature = String.Format("{0}\n\n{1}\n{2}\n{3}",
                  method,
                  "application/atom+xml",
                  now.ToString("R", System.Globalization.CultureInfo.InvariantCulture),
                  GetCanonicalizedResource(request.RequestUri, StorageAccount)
                  );
          }
          else
          {
              MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}",
                  method,
                  (method == "GET" || method == "HEAD") ? String.Empty : request.ContentLength.ToString(),
                  ifMatch,
                  GetCanonicalizedHeaders(request),
                  GetCanonicalizedResource(request.RequestUri, StorageAccount),
                  md5
                  );
          }
          byte[] SignatureBytes = System.Text.Encoding.UTF8.GetBytes(MessageSignature);
          System.Security.Cryptography.HMACSHA256 SHA256 = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(StorageKey));
          String AuthorizationHeader = "SharedKey " + StorageAccount + ":" + Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));
          return AuthorizationHeader;
      }
  
      // Get canonicalized headers.
  
      public string GetCanonicalizedHeaders(HttpWebRequest request)
      {
          ArrayList headerNameList = new ArrayList();
          StringBuilder sb = new StringBuilder();
          foreach (string headerName in request.Headers.Keys)
          {
              if (headerName.ToLowerInvariant().StartsWith("x-ms-", StringComparison.Ordinal))
              {
                  headerNameList.Add(headerName.ToLowerInvariant());
              }
          }
          headerNameList.Sort();
          foreach (string headerName in headerNameList)
          {
              StringBuilder builder = new StringBuilder(headerName);
              string separator = ":";
              foreach (string headerValue in GetHeaderValues(request.Headers, headerName))
              {
                  string trimmedValue = headerValue.Replace("\r\n", String.Empty);
                  builder.Append(separator);
                  builder.Append(trimmedValue);
                  separator = ",";
              }
              sb.Append(builder.ToString());
              sb.Append("\n");
          }
          return sb.ToString();
      }
  
      // Get header values.
  
      public ArrayList GetHeaderValues(NameValueCollection headers, string headerName)
      {
          ArrayList list = new ArrayList();
          string[] values = headers.GetValues(headerName);
          if (values != null)
          {
              foreach (string str in values)
              {
                  list.Add(str.TrimStart(null));
              }
          }
          return list;
      }
  
      // Get canonicalized resource.
  
      public string GetCanonicalizedResource(Uri address, string accountName)
      {
          StringBuilder str = new StringBuilder();
          StringBuilder builder = new StringBuilder("/");
          builder.Append(accountName);
          builder.Append(address.AbsolutePath);
          str.Append(builder.ToString());
          NameValueCollection values2 = new NameValueCollection();
          if (!IsTableStorage)
          {
              //Uri.EscapeDataString(...)
              //WebUtility.HtmlEncode(...)     
              //https://stackoverflow.com/questions/36315/alternative-to-httputility-for-net-3-5-sp1-client-framework
              //NameValueCollection values = HttpUtility.ParseQueryString(address.Query);
              //foreach (string str2 in values.Keys)
              //{
              //    ArrayList list = new ArrayList(values.GetValues(str2));
              //    list.Sort();
              //    StringBuilder builder2 = new StringBuilder();
              //    foreach (object obj2 in list)
              //    {
              //        if (builder2.Length &gt; 0)
              //        {
              //            builder2.Append(",");
              //        }
              //        builder2.Append(obj2.ToString());
              //    }
              //    values2.Add((str2 == null) ? str2 : str2.ToLowerInvariant(), builder2.ToString());
              //}
          }
          ArrayList list2 = new ArrayList(values2.AllKeys);
          list2.Sort();
          foreach (string str3 in list2)
          {
              StringBuilder builder3 = new StringBuilder(string.Empty);
              builder3.Append(str3);
              builder3.Append(":");
              builder3.Append(values2[str3]);
              str.Append("\n");
              str.Append(builder3.ToString());
          }
          return str.ToString();
      }
  
      #endregion
  </code></pre>