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)。