HTTPリクエストの認証
Windows Azure Storageにアクセスするには、HTTPリクエストに、Authorization(認証)ヘッダーを追加します。
REST APIのAuthentication Schemesでは、次のように形式が定められています。
Authorization: "[SharedKey|SharedKeyLite] <AccountName>:<Signature>"
SharedKeyとSharedKeyLiteのどちらを選択するかで、その後に続く、<Signature>の部分のスキーマが異なってきます。ブロブやキューではSharedKeyのみ使用可能で、テーブルの場合どちらかをを選択することができます。<AccountName>の部分には、ストレージアカウントを指定します。
この最後に来る<Signature>の部分は、REST APIの仕様で定められた文字列(HTTPメソッド、MIMEコンテンツタイプなどの情報を、改行コードで連結したもの)を認証キー(SharedKey)を用いてHMAC-SHA256アルゴリズムで署名したものです。
この署名の際に使用する認証キー(SharedKey)は、ストレージアカウントの作成時に、エンドポイントと共に取得することができます(ストレージアカウントと認証キーの実際の取得方法については、前回の記事を参照してください)。また、サインインしたAzure Services Developer Portal上で、いつでも再生成することができます。ローカル環境のDevelopment Storage上では、この認証キーの値は、エンドポイントと同じく固定値となります。
サンプルコードでは、BlobStorageUtilityクラスのToSignatureStringメソッドで、認証キーでの署名を行っています。受け取った文字列をバイト配列に変換し(※1)、認証キーを用いてHMAC-SHA256アルゴリズムで署名します(※2)。
private static string ToSignatureString(string str)
{
string signatureString = String.Empty;
// Windows Azure Storageの認証キーをバイト配列に変換
byte[] sharedKeyByte = Convert.FromBase64String(accountSharedKey);
// 文字列をバイト配列に変換
byte[] signatureStringBytes = Encoding.UTF8.GetBytes(str); // ※1
// HMAC-SHA256アルゴリズムで署名
using (HMACSHA256 hmacsha256 = new HMACSHA256(sharedKeyByte))
{
signatureString = System.Convert.ToBase64String(
hmacsha256.ComputeHash(signatureStringBytes)); // ※2
}
return signatureString;
}
Authentication Schemesの仕様の詳細については、msdnの「Authentication Schemes」を参照してください。
メタデータの設定
コンテナやブロブにメタデータを設定したい場合には、次のような形式で、HTTPリクエストにヘッダーを追加します。
x-ms-meta-{メタデータ名}:{メタデータ値}
例えば、(サンプルで行っているように)titleという名前のメタデータをブロブに設定する場合は、
x-ms-meta-title:青い花のズーム写真
というように、Put BlobのHTTPリクエストにヘッダーを追加します(実際にはメタデータの値はURLエンコードする必要があります)。
サンプルコードでは、BlobStorageUtilityクラスのPutBlobRequestメソッドで、x-ms-meta-titleというヘッダー名を使用して画像のタイトル情報を追加しています(※1)。
HttpWebRequest request = null;
(省略)
// HTTPリクエストを作成
request = (HttpWebRequest)WebRequest.Create(uri);
(省略)
// x-ms-meta-titleヘッダーを追加(メタデータとしてタイトル情報を追加)
request.Headers.Add("x-ms-meta-title", HttpUtility.UrlEncode(title)); // ※1
レスポンスの仕様
リクエストの結果は、HTTPレスポンスのステータスコードで判断します。リクエストが成功だったのか、エラーの場合にはその理由も、このステータスコードにより判断することができます。例えば、コンテナ作成が成功した場合には、201(Created)が返ってきます。
REST APIでは、使用するHTTPメソッドで、成功時のステータスコードが決まっています。以下にメソッドごとのステータスコードをまとめます。
| HTTPメソッド | 成功時のステータスコード |
| PUT | 201(Created) |
| GET | 200(OK) |
| DELETE | 200(OK) または 202(Accepted) |
エラー時のステータスコードについては、さまざまな値が定義されています。詳細については、msdnの「Status and Error Codes」を参照してください。
さらに、リクエストによっては、レスポンスヘッダに値が格納されたり、レスポンスボディにXMLデータやバイナリデータが含まれることがあります。例えば、ブロブの列挙(List Blobs)の場合、レスポンスボディにXMLデータが含まれ、その中にコンテナ内のブロブの情報が列挙されています。また、ブロブの取得(Get Blob)の場合なら、レスポンスヘッダにはデータサイズなどのコンテンツ情報が、レスポンスボディにはブロブのバイナリデータが含まれます。
サンプルコードでは、Default.aspx.csのDisplayメソッドで、ブロブの列挙(List Blobs)のリクエストでレスポンスボディに格納されたXMLデータの解析を行っています。
// HTTPレスポンスを取得
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK)
{
using (Stream stream = response.GetResponseStream())
{
XmlReader reader = XmlReader.Create(stream); // ※1
XDocument doc = XDocument.Load(reader); // ※2
var blobList = from list in doc.Descendants("Blob")
select new BlobData
{
BlobUrl = (string)list.Element("Url"),
ImageUrl = "GetImage.aspx?url=" + (string)list.Element("Url")
}; // ※3
DataList1.DataSource = blobList;
DataList1.DataBind();
}
}
else
{
(省略)
}
}
レスポンスボディに格納されたストリームから、XmlReaderオブジェクトを作成します(※1)。次に、XmlReaderオブジェクトからXMLデータを読み込み(※2)、LINQを使用してブロブのリストを取得します(※3)。
