为azure blob put请求获取403禁止webexception

时间:2011-01-06 07:17:40

标签: azure

我正在使用此代码使用rest api将一些文本直接上传到azure blob。我得到了一个被禁止的webexception 403。有人会告诉我我的代码在哪里出错

    private String CreateAuthorizationHeader(String canonicalizedString, CloudBlob blob)
    {
        String signature = string.Empty;


        using (HMACSHA256 hmacSha256 = new HMACSHA256())
        {
            Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
            signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
        }


        String authorizationHeader = String.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", "SharedKeyLite", myaccount, signature);

        return authorizationHeader;
   }

    private void PutBlob(String containerName, String blobName , CloudBlob blob)
    {
        String requestMethod = "PUT";

        String urlPath = String.Format("{0}",  blobName);

        String storageServiceVersion = "2009-10-01";

        String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);

       // if (uploadPST.HasFile)
      //  {
            string content = "Sample file";
            // Stream content = uploadPST.FileBytes; 
            UTF8Encoding utf8Encoding = new UTF8Encoding();
            Byte[] blobContent = utf8Encoding.GetBytes(content);
            Int32 blobLength = blobContent.Length;


            const String blobType = "BlockBlob";

          /*  String canonicalizedHeaders = String.Format(
                  "x-ms-blob-type:{0}\nx-ms-date:{1}\nx-ms-version:{2}",
                  blobType,
                  dateInRfc1123Format,
                  storageServiceVersion);*/

            String canonicalizedHeaders = String.Format(
                  "x-ms-date:{0}\nx-ms-meta-m1:{1}\nx-ms-meta-m1:{2}",
                   dateInRfc1123Format,
                  "v1",
                  "v2");

            String canonicalizedResource = String.Format("/{0}/{1}", myaccount, urlPath);

           String stringToSign = String.Format(
                  "{0}\n\n{1}\n\n{2}\n{3}",
                  requestMethod,
                  "text/plain; charset=UTF-8",
                  canonicalizedHeaders,
                  canonicalizedResource);



            String authorizationHeader = CreateAuthorizationHeader(stringToSign, blob);

            Uri uri = new Uri(CloudStorageAccount.FromConfigurationSetting("DataConnectionString").BlobEndpoint + "/" + urlPath);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = requestMethod;


           // request.Headers.Add("x-ms-blob-type", blobType);
            request.Headers.Add("x-ms-date", dateInRfc1123Format);
          //  request.Headers.Add("x-ms-version", storageServiceVersion);
            request.Headers.Add("Authorization", authorizationHeader);
            request.ContentLength = blobLength;

            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(blobContent ,0 ,blobLength);
            }

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                String ETag = response.Headers["ETag"];
            }
      //  }
    }

1 个答案:

答案 0 :(得分:0)

首先,使用默认构造函数构造HMACSHA256对象 - 这会导致生成随机密钥并用于签名。你想要的是接受字符串的重载 - 并传递azure帐户密钥。

尽管如此,“手动”签署请求可能会非常棘手,因为有很多事情要做,而且很容易弄乱或忘记某些事情。相反,我建议您使用SignRequest类(msdn doc)的StorageCredentialsAccountAndKey方法,例如;

// ...there exists a request object, and strings for the account name and key

var creds = new StorageCredentialsAccountAndKey(accountName, accountKey);
creds.SignRequest(request);

这将执行正确签署请求所需的一切,包括创建规范化的标题字符串,创建具有正确格式的日期等。