Neutral Scent

App developments & Gadgets

Azure Table StorageをRESTで

アクセスするサンプル(ASP.NET)。
MSDNAuthentication Schemesの項目でSharedKeyLiteの記述の理解に苦戦した。



using System;
using System.Net;
using System.IO;
using System.Text;
using System.Globalization;
using System.Security.Cryptography;

namespace WebRole1
{
public partial class _Default : System.Web.UI.Page
{
public string tableEndPoint { get; set; }
public string accountName { get; set; }
public string sharedKey { get; set; }
private string msVersion = "2009-09-19";

protected void Button1_Click(object sender, EventArgs e)
{
this.tableEndPoint = "http://127.0.0.1:10002/devstoreaccount1/";
this.accountName = "devstoreaccount1";
this.sharedKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";

TextBox1.Text = GetEntity("SampleTable", "87743227-da94-41c2-b266-358a46072dfd", "11e48305-6284-4c79-b657-0d8a64859282");
}

private string GetEntity(String tableName, String partitionKey, String rowKey)
{
string path = String.Format("{0}(PartitionKey='{1}',RowKey='{2}')", tableName, partitionKey, rowKey);
Uri uri = new Uri(this.tableEndPoint + path);
string dateInRfc1123Format = DateTime.UtcNow.ToString("R");
string authorizationHeader = CreateAuthorizationSharedKeyLiteHeader(uri.AbsolutePath, dateInRfc1123Format);

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.Headers.Add("x-ms-date", dateInRfc1123Format);
request.Headers.Add("x-ms-version", this.msVersion);
request.Headers.Add("Authorization", authorizationHeader);
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");
request.Accept = "application/atom+xml,application/xml";
//request.UserAgent = "Microsoft ADO.NET Data Services";

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream dataStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataStream))
{
return reader.ReadToEnd();
}
}
}

private string CreateAuthorizationSharedKeyLiteHeader(string canonicalizedResource, string date)
{
string tosign = date + "\n/" + this.accountName + canonicalizedResource;
string sig = MacSha(tosign, Convert.FromBase64String(this.sharedKey));

return string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", "SharedKeyLite", this.accountName, sig);
}

private static string MacSha(string canonicalizedString, byte[] key)
{
byte[] dataToMac = Encoding.UTF8.GetBytes(canonicalizedString);
using (HMACSHA256 hmacsha1 = new HMACSHA256(key))
{
return Convert.ToBase64String(hmacsha1.ComputeHash(dataToMac));
}
}
}
}

動作確認はDevelopment Fabricのみで実クラウドでは未確認。
参考:
MSDN Forum > Microsoft Visual Studio 2010 Beta 2 Forums > Windows Azure
Insert Entity (Azure Table Storage)
http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/41578289-cfe2-41f1-94f0-c771da0aa84c