共有キーによる承認

ストレージ サービスに対して行われたすべての要求は、パブリックまたは署名付きアクセスで使用可能になった BLOB またはコンテナー リソースに対する要求でない限り、承認される必要があります。 要求を承認する 1 つのオプションは、この記事で説明されている共有キーを使用することです。

ヒント

Azure Storage は、BLOB、ファイル、キュー、およびテーブル サービスへの要求の ID ベースの承認のためのMicrosoft Entra IDとの統合を提供します。 Microsoft Entra IDでは、ロールベースのアクセス制御 (RBAC) を使用して、BLOB、ファイル、キュー、テーブルのリソースへのアクセスをユーザー、グループ、またはアプリケーションに付与できます。 Microsoft Entra IDは、共有キーと同様に、アカウント アクセス キーをアプリケーションに格納せずにストレージ リソースへのアクセスを承認するために使用できます。 詳細については、「Microsoft Entra IDで承認する」を参照してください。

BLOB、キュー、テーブル、およびファイル サービスは、バージョン 2009-09-19 以降 (BLOB、キュー、およびテーブル サービスの場合) とバージョン 2014-02-14 以降 (ファイル サービスの場合) の次の共有キー承認スキームをサポートしています。

  • BLOB、キュー、およびファイル サービスの共有キー。 共有キー承認スキームを使用して、BLOB、キュー、およびファイル サービスに対して要求を行います。 バージョン 2009-09-19 以降の共有キー承認では、セキュリティを強化するために拡張署名文字列がサポートされており、この拡張署名を使用して承認するようにサービスを更新する必要があります。

  • テーブル サービスに対する共有キー。 共有キー承認スキームを使用して、REST API を使用して Table サービスに対して要求を行います。 バージョン 2009-09-19 以降の Table Service の共有キー承認では、以前のバージョンの Table Service と同じ署名文字列が使用されます。

  • 共有キー Lite。 Blob、Queue、Table、File の各サービスに対して要求を行うには、Shared Key Lite 承認スキームを使用します。

    Blob サービスと Queue サービスのバージョン 2009-09-19 以降では、共有キー Lite 承認では、以前のバージョンの BLOB およびキュー サービスで共有キーに対してサポートされていたのと同じ署名文字列の使用がサポートされています。 したがって、共有キー Lite を使用すると、署名文字列を更新しないで BLOB およびキュー サービスに対する要求を行うことができます。

承認された要求には、 または x-ms-date ヘッダーと ヘッダーの Date 2 つのヘッダーがAuthorization必要です。 以下のセクションでは、これらのヘッダーの作成方法について説明します。

重要

Azure Storage では HTTP と HTTPS の両方がサポートされていますが、HTTPS の使用を強くお勧めします。

注意

コンテナーまたは BLOB は、コンテナーのアクセス許可を設定することで、パブリック アクセスに使用できます。 詳細については、「 Azure Storage リソースへのアクセスの管理」を参照してください。 コンテナー、BLOB、キュー、またはテーブルは、共有アクセス署名を使用して署名付きアクセスに使用できます。共有アクセス署名は、別のメカニズムを介して承認されます。 詳細については、「 共有アクセス署名を使用してアクセスを委任 する」を参照してください。

Date ヘッダーの指定

承認されたすべての要求には、要求の協定世界時 (UTC) タイムスタンプを含める必要があります。 タイムスタンプは、x-ms-date ヘッダーまたは標準の HTTP/HTTPS Date ヘッダーで指定できます。 要求で両方のヘッダーを指定した場合は、x-ms-date の値が要求の作成時刻として使用されます。

ストレージ サービスは、要求がサービスに到着した時刻によって、要求が作成されてから 15 分以上経過していないことを確認します。 これにより、再生攻撃などの特定のセキュリティ攻撃を防ぎます。 この検査で問題があると、サーバーは応答コード 403 (Forbidden) を返します。

注意

ヘッダーは x-ms-date 、一部の HTTP クライアント ライブラリとプロキシによってヘッダーが自動的に設定 Date され、承認された要求に含めるためにその値を読み取る機会が開発者に与えられないためです。 x-ms-date を設定する場合は、Date ヘッダーについては空の値で署名を作成します。

Authorization ヘッダーの指定

承認された要求には ヘッダーを Authorization 含める必要があります。 このヘッダーが含まれていない場合、要求は匿名であり、パブリック アクセス用にマークされているコンテナーまたは BLOB、または委任されたアクセス用に共有アクセス署名が提供されているコンテナー、BLOB、キュー、またはテーブルに対してのみ成功します。

要求を承認するには、要求を行っているアカウントのキーを使用して要求に署名し、要求の一部としてその署名を渡す必要があります。

Authorization ヘッダーの形式は次のとおりです。

Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"  

SharedKey または SharedKeyLite は、認証スキームの名前です。AccountName は、リソースを要求しているアカウントの名前です。Signature は、要求から作成され、SHA256 アルゴリズムを使用して計算された後、Base64 エンコーディングを使用してエンコードされた、Hash-based Message Authentication Code (HMAC) です。

注意

パブリック アクセスが可能なリソースの場合、異なるアカウントの下にあるリソースを要求できます。

以下のセクションでは、Authorization ヘッダーの作成方法について説明します。

署名文字列の構築

署名文字列の作成方法は、承認対象のサービスとバージョン、および使用している承認スキームによって異なります。 署名文字列を作成するときは、以下の点に注意してください。

  • 文字列の VERB 部分は、GET や PUT などの HTTP 動詞であり、大文字を使用する必要があります。

  • BLOB、Queue、および File サービスの共有キー承認の場合、署名文字列に含まれる各ヘッダーは 1 回だけ表示できます。 いずれかのヘッダーが重複している場合、サービスはステータス コード 400 (Bad Request) を返します。

  • すべての標準 HTTP ヘッダーの値は、署名形式において示されている順序で文字列に含まれる必要があります (ヘッダー名は含まれません)。 これらのヘッダーは、要求の一部として指定されていない場合は空にすることができます。その場合は、改行文字のみが必要です。

  • ヘッダーが x-ms-date 指定されている場合は、要求でヘッダーが指定されているかどうかに関係なく、ヘッダーを無視 Date し、署名文字列の部分に空の行を Date 指定するだけです。 この場合は、ヘッダーを追加 するための正規化されたヘッダー文字列の構築 に関するセクションの手順に x-ms-date 従います。

    Dateの両方x-ms-dateを指定してもかまいません。この場合、サービスは のx-ms-date値を使用します。

  • x-ms-date ヘッダーを指定しない場合は、Date ヘッダーを署名文字列で指定します (ヘッダー名は含めません)。

  • 示されているすべての改行文字 (\n) は署名文字列に必要です。

  • 署名文字列には、正規化されたヘッダーと、正規化されたリソース文字列が含まれます。 これらの文字列を正規化することで、文字列は Azure Storage で認識される標準形式になります。 署名文字列を構成する CanonicalizedHeaders および CanonicalizedResource 文字列の作成の詳細については、後の該当するセクションを参照してください。

BLOB、キュー、およびファイル サービス (共有キーの承認)

2009-09-19 バージョン以降の BLOB サービスまたはキュー サービスと 2014-02-14 バージョン以降のファイル サービスに対する要求の共有キー署名文字列をエンコードするには、次の形式を使用します。

StringToSign = VERB + "\n" +  
               Content-Encoding + "\n" +  
               Content-Language + "\n" +  
               Content-Length + "\n" +  
               Content-MD5 + "\n" +  
               Content-Type + "\n" +  
               Date + "\n" +  
               If-Modified-Since + "\n" +  
               If-Match + "\n" +  
               If-None-Match + "\n" +  
               If-Unmodified-Since + "\n" +  
               Range + "\n" +  
               CanonicalizedHeaders +   
               CanonicalizedResource;  

重要

現在のバージョンでは、要求のコンテンツ長が 0 の場合、Content-Length フィールドは空の文字列である必要があります。 バージョン 2014-02-14 以前では、コンテンツの長さは 0 であっても含まれていました。 以前の動作の詳細については、以下を参照してください。

次の例は、 Get Blob 操作のシグネチャ文字列を示しています。 ヘッダー値がない場合は、改行文字のみが指定されます。

GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer\ncomp:metadata\nrestype:container\ntimeout:20  

同じ文字列の各部分を 1 行ごとに分解すると次のようになります。

GET\n /*HTTP Verb*/  
\n    /*Content-Encoding*/  
\n    /*Content-Language*/  
\n    /*Content-Length (empty string when zero)*/  
\n    /*Content-MD5*/  
\n    /*Content-Type*/  
\n    /*Date*/  
\n    /*If-Modified-Since */  
\n    /*If-Match*/  
\n    /*If-None-Match*/  
\n    /*If-Unmodified-Since*/  
\n    /*Range*/  
x-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n    /*CanonicalizedHeaders*/  
/myaccount /mycontainer\ncomp:metadata\nrestype:container\ntimeout:20    /*CanonicalizedResource*/  

次に、この文字列を UTF-8 エンコード署名文字列に対する HMAC-SHA256 アルゴリズムを使用してエンコードし、Authorization ヘッダーを作成して、ヘッダーを要求に追加します。 次の例は、同じ操作に対する Authorization ヘッダーを示しています。

Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=  

Blob サービスと Queue サービスのバージョン 2009-09-19 以降で共有キー承認を使用するには、この拡張署名文字列を使用するようにコードを更新する必要があります。

可能な限り少ない変更で BLOB サービスとキュー サービスのバージョン 2009-09-19 以降にコードを移行する場合は、共有キーではなく Shared Key Lite を使用するように既存 Authorization のヘッダーを変更できます。 共有キー Lite 認証で必要な署名形式は、2009-09-19 より前のバージョンの BLOB およびキュー サービスで共有キーに対して必要な形式と同じです。

重要

読み取りアクセスの geo レプリケーション (RA-GRS) が有効になっているストレージ アカウントの第 2 の場所にアクセスする場合、認証ヘッダーに -secondary 指示を含めないでください。 認証目的のために、第 2 アクセスであっても、アカウント名は常に第 1 の場所の名前になります。

バージョン 2014-02-14 以前の Content-Length ヘッダー

バージョン 2014-02-14 以前を使用する場合、 が 0 の場合 Content-Length は、 の部分を Content-LengthStringToSign0設定します。 通常、これは空の文字列になります。

たとえば、次の要求の場合、ヘッダーの Content-Length 値は、0 の場合でも に StringToSign 含まれます。

PUT http://myaccount/mycontainer?restype=container&timeout=30 HTTP/1.1  
x-ms-version: 2014-02-14  
x-ms-date: Fri, 26 Jun 2015 23:39:12 GMT  
Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=  
Content-Length: 0

StringToSign 次のように構築されます。

Version 2014-02-14 and earlier:
PUT\n\n\n\n0\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2014-02-14\n/myaccount/mycontainer\nrestype:container\ntimeout:30

2014-02-14 以降のバージョンでは、 StringToSign には の空の文字列 Content-Lengthが含まれている必要があります。

Version 2015-02-21 and later:
PUT\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer\nrestype:container\ntimeout:30

テーブル サービス (共有キーの承認)

サービスが REST API を使用して要求を行っている場合は、共有キー承認を使用して Table サービスに対して行われた要求を承認する必要があります。 テーブル サービスに対する共有キーの署名文字列の形式は、すべてのバージョンで同じです。

Table サービスに対する要求の共有キー署名文字列は、BLOB または Queue サービスに対する要求の場合とは若干異なります。文字列の部分は含 CanonicalizedHeaders まれません。 また、テーブル サービスの場合は、Date ヘッダーを設定する場合でも、x-ms-date ヘッダーを空にすることはできません。 要求に x-ms-date を設定する場合は、その値を Date ヘッダーにも使用します。

REST API を使用して行われるテーブル サービスに対する要求の署名文字列をエンコードするには、次の形式を使用します。

StringToSign = VERB + "\n" +
               Content-MD5 + "\n" +
               Content-Type + "\n" +  
               Date + "\n" +  
               CanonicalizedResource;  

注意

バージョン 2009-09-19 以降の Table Service では、すべての REST 呼び出しに DataServiceVersion および MaxDataServiceVersion ヘッダーを含める必要があります。 詳細については、「 OData Data Service バージョン ヘッダーの設定 」を参照してください。

BLOB、キュー、およびファイル サービス (Shared Key Lite 承認)

Shared Key Lite 承認を使用して、BLOB およびキュー サービスの 2009-09-19 バージョン以降、およびファイル サービスのバージョン 2014-02-14 以降に対して行われた要求を承認できます。

Shared Key Lite の署名文字列は、2009-09-19 より前のバージョンの BLOB および Queue サービスでの共有キー承認に必要な署名文字列と同じです。 そのため、Blob および Queue サービスのバージョン 2009-09-19 に最小限の変更を加えてコードを移行する場合は、署名文字列自体を変更せずに、Shared Key Lite を使用するようにコードを変更できます。 Shared Key Lite を使用すると、バージョン 2009-09-19 以降で共有キーを使用して提供される強化されたセキュリティ機能を利用できなくなります。

BLOB またはキュー サービスに対する要求の署名文字列をエンコードするには、次の形式を使用します。

StringToSign = VERB + "\n" +  
               Content-MD5 + "\n" +  
               Content-Type + "\n" +  
               Date + "\n" +  
               CanonicalizedHeaders +   
               CanonicalizedResource;  

次の例は、 Put Blob 操作の署名文字列を示しています。 Content-MD5 ヘッダーの行が空であることに注意してください。 文字列で示されているヘッダーは名前と値のペアであり、新しい BLOB のカスタム メタデータ値を指定します。

PUT\n\ntext/plain; charset=UTF-8\n\nx-ms-date:Sun, 20 Sep 2009 20:36:40 GMT\nx-ms-meta-m1:v1\nx-ms-meta-m2:v2\n/testaccount1/mycontainer/hello.txt  

次に、この文字列を UTF-8 エンコード署名文字列に対する HMAC-SHA256 アルゴリズムを使用してエンコードし、Authorization ヘッダーを作成して、ヘッダーを要求に追加します。 次の例は、同じ操作に対する Authorization ヘッダーを示しています。

Authorization: SharedKeyLite myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=  

Table Service (Shared Key Lite 承認)

Shared Key Lite 承認を使用して、Table サービスの任意のバージョンに対して行われた要求を承認できます。

共有キー Lite を使用して行われるテーブル サービスに対する要求の署名文字列をエンコードするには、次の形式を使用します。

StringToSign = Date + "\n"
               CanonicalizedResource  

次の例は、 テーブルの作成 操作のシグネチャ文字列を示しています。

Sun, 11 Oct 2009 19:52:39 GMT\n/testaccount1/Tables  

次に、この文字列を HMAC-SHA256 アルゴリズムを使用してエンコードし、Authorization ヘッダーを作成して、ヘッダーを要求に追加します。 次の例は、同じ操作に対する Authorization ヘッダーを示しています。

Authorization: SharedKeyLite testaccount1:uay+rilMVayH/SVI8X+a3fL8k/NxCnIePdyZSkqvydM=  

正規化されたヘッダー文字列の構築

署名文字列の CanonicalizedHeaders 部分を作成するには、次の手順を使用します。

  1. x-ms- ヘッダーなど、リソースの x-ms-date で始まるすべてのヘッダーを取得します。

  2. 各 HTTP ヘッダー名を小文字に変換します。

  3. ヘッダーをヘッダー名のアルファベット順に並べ替えます。 各ヘッダーは、文字列内で 1 回だけ表示できます。

    注意

    辞書式の順序は 、従来のアルファベット順と常に一致するとは限りません。

  4. ヘッダー値内の線形空白文字を 1 つのスペースに置き換えます。

線形空白には、復帰/改行 (CRLF)、スペース、タブが含まれます。 詳細については 、RFC 2616、セクション 4.2 を参照してください。 引用符で囲まれた文字列内の空白文字は置き換えないでください。

  1. ヘッダー内のコロンの周囲の空白をトリミングします。

  2. 最後に、結果のリストの各正規化されたヘッダーに改行文字を追加します。 このリストのすべてのヘッダーを 1 つの文字列に連結することで、CanonicalizedHeaders 文字列を作成します。

正規化されたヘッダー文字列の例を次に示します。

x-ms-date:Sat, 21 Feb 2015 00:48:38 GMT\nx-ms-version:2014-02-14\n

注意

サービス バージョン 2016-05-31 より前では、空の値を持つヘッダーは署名文字列から省略されていました。 これらは、コロン文字の直後に終わる改行で CanonicalizedHeaders で表されるようになりました。

正規化されたリソース文字列の構築

署名文字列の CanonicalizedResource 部分は、要求の対象であるストレージ サービス リソースを表します。 リソースの URI から抽出される CanonicalizedResource 文字列のすべての部分は、URI の場合と同じように正確にエンコードする必要があります。

CanonicalizedResource 文字列としては 2 つの形式がサポートされています。

  • Blob および Queue サービスのバージョン 2009-09-19 以降、およびファイル サービスのバージョン 2014-02-14 以降の共有キー承認をサポートする形式。

  • すべてのバージョンのテーブル サービスの共有キーと共有キー Lite、およびバージョン 2009-09-19 以降の BLOB サービスとキュー サービスの共有キー Lite をサポートする形式。 この形式は、以前のバージョンのストレージ サービスで使用されているものと同じです。

アクセスするリソースの URI の作成については、次のいずれかのトピックを参照してください。

重要

読み取りアクセスの geo レプリケーション (RA-GRS) でストレージ アカウントが複製されるとき、第 2 の場所のリソースにアクセスする場合、–secondary 文字列に CanonicalizedResource 指示を含めないでください。 CanonicalizedResource 文字列 URI で使用されるリソース URI は第 1 の場所のリソースの URI にする必要があります。

注意

ストレージ エミュレーターに対して承認している場合は、アカウント名が文字列に CanonicalizedResource 2 回表示されます。 これは予期されることです。 Azure ストレージ サービスに対して承認している場合、アカウント名は文字列に CanonicalizedResource 1 回だけ表示されます。

2009-09-19 以降の共有キー形式

この形式では、Blob および Queue サービスの 2009-09-19 バージョン以降、および 2014-02-14 バージョン以降のファイル サービスの共有キー承認がサポートされます。 この形式の CanonicalizedResource 文字列は次のように作成します。

  1. 先頭に空の文字列 ("")、次にスラッシュ (/)、次にアクセス対象のリソースを所有しているアカウントの名前を追加します。

  2. リソースのエンコードされた URI パスを追加します。クエリ パラメーターは指定しません。

  3. comp パラメーターが存在する場合はそれも含めて、リソース URI に対するすべてのクエリ パラメーターを取得します。

  4. すべてのパラメーター名を小文字に変換します。

  5. クエリ パラメーターをパラメーター名のアルファベット順に並べ替えます。

  6. 各クエリ パラメーターの名前と値を URL でデコードします。

  7. 各名前と値のペアの前に改行文字 (\n) を含めます。

  8. 各クエリ パラメーターの名前と値を次の形式で文字列に追加します。名前と値の間にコロン (:) を必ず追加します。

    parameter-name:parameter-value

  9. クエリ パラメーターに複数の値がある場合は、すべての値を辞書順に並べ替えて、コンマ区切りのリストとして追加します。

    parameter-name:parameter-value-1,parameter-value-2,parameter-value-n

正規化されたリソース文字列の作成では、次の規則に留意してください。

  • クエリ パラメーターの値では改行文字 (\n) を使用しないようにします。 使用する必要がある場合は、正規化されたリソース文字列の形式に影響がないことを確認します。

  • クエリ パラメーターの値ではコンマを使用しないようにします。

指定された要求 URI から作成できるため、署名文字列の部分を示す CanonicalizedResource 例をいくつか次に示します。

Get Container Metadata  
   GET http://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=metadata
CanonicalizedResource:  
    /myaccount/mycontainer\ncomp:metadata\nrestype:container  
  
List Blobs operation:  
    GET http://myaccount.blob.core.windows.net/container?restype=container&comp=list&include=snapshots&include=metadata&include=uncommittedblobs  
CanonicalizedResource:  
    /myaccount/mycontainer\ncomp:list\ninclude:metadata,snapshots,uncommittedblobs\nrestype:container  
  
Get Blob operation against a resource in the secondary location:  
   GET https://myaccount-secondary.blob.core.windows.net/mycontainer/myblob  
CanonicalizedResource:  
    /myaccount/mycontainer/myblob

2009-09-19 以降の Shared Key Lite と Table Service の形式

この形式は、すべてのバージョンの Table Service の共有キーと共有キー Lite、バージョン 2009-09-19 以降の BLOB Service とキュー サービス、バージョン 2014-02-14 以降のファイル サービスの共有キー Lite をサポートします。 この形式は、以前のバージョンのストレージ サービスで使用されているものと同じです。 この形式の CanonicalizedResource 文字列は次のように作成します。

  1. 先頭に空の文字列 ("")、次にスラッシュ (/)、次にアクセス対象のリソースを所有しているアカウントの名前を追加します。

  2. リソースのエンコードされた URI パスを追加します。 要求の URI がリソースのコンポーネントのアドレスを指定している場合は、適切なクエリ文字列を追加します。 クエリ文字列には、疑問符と comp パラメーターを含める必要があります (例: ?comp=metadata)。 クエリ文字列には他のパラメーターを含めないでください。

署名のエンコード

署名をエンコードするには、UTF-8 でエンコードされた署名文字列に対して HMAC-SHA256 アルゴリズムを呼び出し、結果を Base64 としてエンコードします。 ストレージ アカウント キーを Base64 デコードする必要もあることに注意してください。 次の形式を使用します (擬似コードとして示されています)。

Signature=Base64(HMAC-SHA256(UTF8(StringToSign), Base64.decode(<your_azure_storage_account_shared_key>)))  

こちらもご覧ください