Uploading through REST API to blob storage throws (403) Forbidden Error.
-
29 เมษายน 2555 17:46
Can someone help. Am facing same problem.. but using simple code to do things. Can someone help please.
Note - Am able to upload the same data using StorageClient dll.
But with Http, am facing issues. On desktop it says (403) Forbidden Error. I have used Fiddler to fig what my StorageClient is sending & replicated that in HttpWebRequest.
Thanks.
public bool StartGPSDataUpload(Guid raceId) { bool bResult = false; try { string URL = ""; URL = "http://xxxx.blob.core.windows.net/videos/"+ Uri.EscapeDataString("6a3c2acd-8a2f-41ee-9203-137d7ba7ecd5-GPS-test.txt") +"?timeout=90"; WebReq = (HttpWebRequest)HttpWebRequest.Create(URL); WebReq.Method = "PUT"; WebReq.KeepAlive = false; WebReq.Headers["x-ms-version"] = "2011-08-18"; WebReq.UserAgent = "myapp"; WebReq.Headers["x-ms-blob-type"] = "BlockBlob"; WebReq.Headers["x-ms-date"] = DateTime.UtcNow.ToString("R"); WebReq.Headers["Authorization"] = "SharedKey xxxx:ioOqYh7CnftgX8c1DxX5OiRWL1v9TfIJMmTl8m4ogrY="; gpsdataInByte = ReadGPSFile(raceId); WebReq.ContentLength = gpsdataInByte.Length; using (HttpWebResponse response = (HttpWebResponse)WebReq.GetResponse()) { String ETag = response.Headers["ETag"]; System.Windows.Forms.MessageBox.Show(ETag); } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("error - " + ex.ToString()); } return bResult; }
ตอบทั้งหมด
-
29 เมษายน 2555 18:42
How are you deriving the auth signature? I don't see any code that computes the canonicalized resource, headers, etc., and signs them. I think perhaps you're assuming a simpler auth scheme than is actually used by WA storage.- เสนอเป็นคำตอบโดย Arwind - MSFTModerator 30 เมษายน 2555 3:58
- ทำเครื่องหมายเป็นคำตอบโดย Arwind - MSFTModerator 7 พฤษภาคม 2555 3:57
-
30 เมษายน 2555 15:32
Hello Steve,
You are right. I was assuming it to be simpler. I was able to get things working. Thanks for the tip.
For others who may benefit from my stumbles, here is the sample code.
This article was helful http://convective.wordpress.com/2010/08/18/examples-of-the-windows-azure-storage-services-rest-api/
Here is the sample code for others. Usage will be (new AzureStorageHelper()).PutBlob("yourcontainername", "yourblobfilename");
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.Globalization; using System.Net; using System.IO; namespace TestBlobUpload { class AzureStorageConstants { public static string Key="xxxx"; public static string SharedKeyAuthorizationScheme = "SharedKey"; public static string Account="xxxx"; public static string BlobEndPoint="http://xxxxx.blob.core.windows.net/"; } class AzureStorageHelper { public String CreateAuthorizationHeader(String canonicalizedString) { String signature = string.Empty; //UTF8Encoding utf8Encoding = new UTF8Encoding(); //byte[] storageKey = utf8Encoding.GetBytes(AzureStorageConstants.Key); byte[] storageKey = Convert.FromBase64String(AzureStorageConstants.Key); using (HMACSHA256 hmacSha256 = new HMACSHA256(storageKey)) { Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString); signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac)); } String authorizationHeader = String.Format( CultureInfo.InvariantCulture, "{0} {1}:{2}", AzureStorageConstants.SharedKeyAuthorizationScheme, AzureStorageConstants.Account, signature); return authorizationHeader; } public void PutBlob(String containerName, String blobName) { String requestMethod = "PUT"; String urlPath = String.Format("{0}/{1}", containerName, blobName); String storageServiceVersion = "2011-08-18"; // "2009-09-19"; String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture); String content = "The Name of This Band is Talking Heads"; 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-mx-blob-content-length:{3}\nx-ms-blob-type:{0}\nx-ms-date:{1}\nx-ms-version:{2}", blobType, dateInRfc1123Format, storageServiceVersion, blobLength.ToString()); */ String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath); String stringToSign = String.Format( "{0}\n\n\n{1}\n\n\n\n\n\n\n\n\n{2}\n{3}", requestMethod, blobLength, canonicalizedHeaders, canonicalizedResource); String authorizationHeader = CreateAuthorizationHeader(stringToSign); Uri uri = new Uri(AzureStorageConstants.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; try { using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(blobContent, 0, blobLength); } using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { String ETag = response.Headers["ETag"]; } System.Windows.Forms.MessageBox.Show("Success"); } catch (WebException webEx) { if (webEx != null) { WebResponse resp = webEx.Response; if (resp != null) { using (StreamReader sr = new StreamReader(resp.GetResponseStream(), true)) { string responseText = sr.ReadToEnd();//This is where details about this 403 message can be found System.Windows.Forms.MessageBox.Show("error - " + responseText); } } } } } } }