すべてのプロダクト
Search
ドキュメントセンター

OpenSearch:OpenSearch API V3 の署名方式

最終更新日:Dec 28, 2024

OpenSearch は、各アクセスリクエストを認証します。このサービスは、AccessKey ペアに基づく対称暗号化を実装して、ユーザーの身元を確認します。各 AccessKey ペアは、AccessKey ID と AccessKey シークレットで構成されます。

AccessKey ID と AccessKey シークレットは、Alibaba Cloud によってユーザーに正式に発行されます。Alibaba Cloud 国際サイト (alibabacloud.com) で AccessKey ペアをリクエストおよび管理できます。AccessKey ID は、ユーザーIDの検証に使用されます。

AccessKey シークレットは、署名文字列を暗号化し、サーバー上で署名文字列を検証するために使用されます。AccessKey シークレットは厳重に管理する必要があります。

対応アプリケーション

  • 高度なアプリケーション

  • 標準アプリケーション

プロトコル

OpenSearch API V3 は HTTP プロトコルのみをサポートしています。

リクエストメソッド

  • データを検索するには、HTTP GET リクエストを送信する必要があります。

  • データを送信するには、HTTP POST リクエストを送信する必要があります。

Authorization ヘッダーの値の計算

HTTP リクエストの Authorization ヘッダーに署名文字列を追加する必要があります。これは、リクエストが認証されていることを示します。HTTP リクエストには、他の必要なヘッダーも含まれている必要があります。このトピックの「例」セクションでは、ヘッダーの例を示します。

Content-Md5、Content-Type、Date、OpenSearch 固有の HTTP ヘッダーなど、すべてのリクエストヘッダーは、署名の計算に使用される必要があります。次の string-to-sign の「Authorization:OPENSEARCH 」の OPENSEARCH の後にスペースを追加する必要があります。

"Authorization: OPENSEARCH " + AccessKeyId + ":" + Signature
Signature = base64(hmac-sha1(AccessKeySecret,
            VERB + "\n"
            + Content-Md5 + "\n"
            + Content-Type + "\n"
            + Date + "\n"
            + CanonicalizedOpenSearchHeaders
            + CanonicalizedResource))

RFC 2104 で定義されている string-to-sign の HMAC 値を計算します

  • RFC 2104 で定義されている HMAC-SHA1 メソッドを使用して、署名文字列を計算します。

  • 署名文字列は UTF-8 でエンコードする必要があります。

  • 中国語が含まれる署名文字列は、最初に UTF-8 でエンコードする必要があります。エンコードされた署名文字列は、AccessKeySecret パラメーターと共に使用されて、最終的な署名文字列が計算されます。

  • 署名文字列の計算に使用されるパラメーターは、上記のサンプルコードと同じ方法でソートする必要があります。

パラメーター

説明

AccessKeyId

必須。リクエストを送信するユーザーの AccessKey ID。このパラメーターは、Authorization ヘッダーに指定する必要があります。

AccessKeySecret

必須。リクエストを送信するユーザーの AccessKey シークレット。AccessKey シークレットは、署名文字列の暗号化と検証に使用されます。

VERB

必須。リクエストメソッド。HTTP リクエストでサポートされているメソッドには、PUT、GET、POST、HEAD、DELETE があります。API 操作によって異なるリクエストメソッドが必要です。

\n

改行。

Content-MD5

HTTP リクエストボディの MD5 値。リクエストにボディがある場合、このパラメーターは必須です。このパラメーターは、受信したリクエストの内容が送信されたリクエストの内容と同じであるかどうかを確認するために使用されます。これにより、リクエストの有効性が保証されます。例:4991ef0788236a8f280fed0db928e74e

データを検索するリクエストなど、ボディがないリクエストの場合は、このパラメーターを指定しないでください。詳細については、RFC 2616 Content-MD5 を参照してください。

Content-Type

例:application/json

Date

必須。リクエストが送信された時刻。ISO 8601 標準でYYYY-MM-DDThh:mm:ssZ 形式で時刻を指定します。時刻は UTC である必要があります。例:2019-02-25T10:09:57Z。リクエストが送信された時刻と OpenSearch サーバーがリクエストを受信した時刻の間隔が 15 分を超えると、サーバーはリクエストを拒否し、HTTP エラーコード 403 を返します。

CanonicalizedOpenSearchHeaders

必須。リクエストを区別するために使用される OpenSearch 固有の HTTP ヘッダー。X-Opensearch- で始まるすべての HTTP リクエストヘッダー(X-Opensearch-Nonce など)は、OpenSearch 固有の HTTP ヘッダーです。署名の計算中に、これらのヘッダーの名前は小文字にする必要があります(x-opensearch-nonce など)。これらのヘッダーをリクエストヘッダーとして使用する場合は、元の形式でヘッダー名を指定します。これらのヘッダーをリクエストヘッダーとして使用しない場合、署名の計算には使用されません。この場合、string-to-sign から CanonicalizedOpenSearchHeaders パラメーターを削除します。

CanonicalizedResource

必須。リクエストのパス。例:/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson

データ検索のリクエスト

リクエスト署名パラメーター

必須

リクエストヘッダー

必須

AccessKeySecret

はい

Date

はい

VERB

はい

X-Opensearch-Nonce

はい

Date

はい

Authorization

はい

x-opensearch-nonce

はい

canonicalized_resource

はい

  • リクエストヘッダーの値は、署名の計算に指定された値と同じである必要があります。

  • Content-Md5、Content-Type、Date、CanonicalizedOpenSearchHeaders、Authorization パラメーターをリクエストヘッダーとして追加することをお勧めします。必要なリクエストヘッダーのみを指定すると、エラーが発生する可能性があります。

  • すべてのリクエストヘッダーは、署名の計算に使用される必要があります。

データプッシュのリクエスト

リクエスト署名パラメーター

必須

リクエストヘッダー

必須

AccessKeySecret

はい

Content-MD5

はい

VERB

はい

Date

はい

Content-MD5

はい

Authorization

はい

Date

はい

canonicalized_resource

はい

  • リクエストヘッダーの値は、署名の計算に指定された値と同じである必要があります。

  • Content-Md5、Content-Type、Date、CanonicalizedOpenSearchHeaders、Authorization パラメーターをリクエストヘッダーとして追加することをお勧めします。必要なリクエストヘッダーのみを指定すると、エラーが発生する可能性があります。

  • すべてのリクエストヘッダーは、署名の計算に使用される必要があります。

CanonicalizedOpenSearchHeaders 文字列の構築

CanonicalizedOpenSearchHeaders パラメーターには、X-Opensearch- で始まるすべての OpenSearch 固有の HTTP ヘッダーが含まれます。他の HTTP ヘッダーはこのセクションには関係ありません。

  1. X-Opensearch- で始まる OpenSearch 固有の HTTP ヘッダーの値を指定します。たとえば、完全な HTTP ヘッダーは X-Opensearch-Nonce : 1551089397451704 です。ヘッダーの値(1551089397451704 など)は、10 桁のタイムスタンプと 100000 から 999999 までの 6 桁のランダムな値で構成されます。次に、値が空のすべての OpenSearch 固有の HTTP ヘッダーを省略します。

  2. 残りのすべての OpenSearch 固有の HTTP ヘッダーをアルファベット順にソートします。

  3. ソートされた HTTP ヘッダーの名前の大文字を小文字に変換します。たとえば、X-Opensearch-Nonce : 1551089397451704x-opensearch-nonce : 1551089397451704 に変換します。

  4. 各ヘッダーとその値の間の区切り文字の両側のスペースをすべて削除します。たとえば、元の HTTP ヘッダーは x-opensearch-nonce : 1551089397451704 です。スペースが削除されると、HTTP ヘッダーは x-opensearch-nonce:1551089397451704 になります。

  5. 各ヘッダーと値のペアを 1 つの項目とみなします。すべての項目を \n 区切り文字で連結して、最終的な CanonicalizedOpenSearchHeaders 文字列を形成します。\n 区切り文字は、最後の項目にも追加する必要があります。

説明

  1. データ検索の HTTP リクエストには、OpenSearch 固有の HTTP ヘッダーが含まれていない場合があります。これらのヘッダーは、署名の計算には使用されません。この場合、「\n」区切り文字は不要であり、CanonicalizedOpenSearchHeaders 文字列を構築する必要はありません。string-to-sign から CanonicalizedOpenSearchHeaders パラメーターを削除します。

  2. リクエストのヘッダーに OpenSearch 固有の HTTP ヘッダーを追加する場合は、小文字で構成される変換された形式でヘッダー名を指定しないでください。元の形式を使用する必要があります。

CanonicalizedResource 文字列の構築

  • 署名文字列は UTF-8 でエンコードする必要があります。中国語が含まれる署名文字列は、最初に UTF-8 でエンコードする必要があります。エンコードされた署名文字列は、AccessKeySecret パラメーターと共に使用されて、最終的な署名文字列が計算されます。

  • データ検索のリクエストの CanonicalizedResource 文字列の形式は、パス + ? + クエリ です。

  • データプッシュのリクエストの CanonicalizedResource 文字列の形式は、パス です。

パス文字列の構築

パス文字列を構築するには、元の文字列をエンコードし、%2F をスラッシュ (/) に置き換え、app_schema_demo をアプリケーションの名前に置き換えます。次に、一般的な 4 つのパス文字列を示します。

  • データ検索のリクエストのパス文字列:/v3/openapi/apps/app_schema_demo/search

  • 候補に基づいてデータを検索するリクエストのパス文字列:/v3/openapi/suggestions/suggestion_name/actions/search

  • アプリケーションを使用してデータを検索するリクエストのパス文字列:/v3/openapi/apps/appid。この場合、appid を検索に使用するアプリケーションの ID に置き換え、認証のために Authorization ヘッダーを指定する必要があります。リクエストパラメーターを指定する必要はありません。

  • データプッシュのリクエストのパス文字列:/v3/openapi/apps/app_schema_demo/tab/actions/bulk。この場合、tab をアプリケーションでデータを受信するために使用するテーブルの名前に置き換える必要があります。

クエリ文字列の構築

クエリ文字列はリクエストパラメーターで構成されます。パラメーターはキーと値のペアの形式で指定されます。CanonicalizedResource 文字列のクエリ文字列を構築するには、次の手順を実行します。

  1. 使用する各リクエストパラメーターに値を割り当て、値が空のリクエストパラメーターを省略します。値が空のリクエストパラメーターは、署名の計算には使用されません。

  2. リクエストパラメーターを、最初に key で、次に value でアルファベット順にソートします。

  3. RFC 3986 標準に基づいて、リクエストパラメーターの keyvalue をエンコードします。次に、等号 (=) を使用して、エンコードされた各リクエストパラメーターのキーと値を連結します。

  4. アンパサンド (&) を使用して、エンコードされたリクエストパラメーターを連結し、値をクエリ文字列として保存します。

  5. パス文字列とクエリ文字列を使用して、パス + ? + クエリの形式で最終的な CanonicalizedResource 文字列を形成します。CanonicalizedResource 文字列の例:/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson

    • CanonicalizedResource 文字列の例には、次のリクエストパラメーターとその値が含まれています。

      • fetch_fields=name

    • CanonicalizedResource 文字列の例には、次のクエリパラメーターと句が含まれています。最初の部分はクエリパラメーターを示し、2 番目の部分はクエリ句とその他の関連句を示します。

      • query=query=name:'document'&&sort=id&&config=format:fulljson

説明

クエリパラメーターの文字列をエンコードする前に、句を二重アンパサンド (&&) で連結する必要があります。データプッシュのリクエストを送信する場合は、パス文字列のみを CanonicalizedResource 文字列として使用する必要があります。

Authorization ヘッダーの構築

Authorization ヘッダーの構築方法については、このトピックの「Authorization ヘッダーの値の計算」セクションを参照してください。たとえば、ユーザーの AccessKey ID が LTAItQcybixt**** で、署名文字列が 1P7tfEh+CU5kFYRXzZ14kkJU**** であるとします。次の Python 3 のサンプルコードは、Authorization ヘッダーを構築します。

headers['Authorization'] = 'OPENSEARCH ' + 'LTAIt****xt****' + ':' + '1P7tf*******4kkJU****'

たとえば、リクエストのヘッダーとパラメーター、およびリクエストメソッドは次のように構成されます。

  • Authorization: OPENSEARCH LTAItQ****R9A0:1P7tfEh+CU******14kkJ****

  • AccessKeySecret: R0OGKs*******khMqHXBfKG

  • リクエストメソッド: GET

  • Content-MD5: サンプルリクエストはデータ検索に使用されるため、このパラメーターは空のままです。

  • Content-Type: application/json

  • Date: 2019-02-25T10:09:57Z

  • CanonicalizedOpenSearchHeaders: x-opensearch-nonce:15510****1704

  • CanonicalizedResource: /v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson

リクエストヘッダー

署名文字列の計算式

'Content-MD5': '','Content-Type': 'application/json','Authorization': 'OPENSEARCH LTA****tR9A0:1P7tfEh+CU****RXzZ14kkJUAMc=','X-Opensearch-Nonce': '1551089397451704','Date': '2019-02-25T10:09:57Z'

Signature = base64(hmac-sha1(AccessKeySecret,VERB + "\n"+ Content-Md5 + "\n"+ Content-Type + "\n"+ Date + "\n"+ CanonicalizedOpenSearchHeaders+ CanonicalizedResource))

R0OGKs*******khMqHXBfKG,GET\n\napplication/json\n2019-02-25T10:09:57Z\nx-opensearch-nonce:1551089397451704\n/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson

説明

リクエストヘッダーの値は、署名の計算に指定された値と同じである必要があります。

署名文字列の計算例

  • この例では、HMAC 値と Base64 エンコード形式を使用して署名文字列を計算します。

Python 3 のサンプルコード:

import hmac
import base64
signature_string = '\n'.join(['GET',
                              '',
                              'application/json',
                              '2019-02-25T10:09:57Z',
                              'x-opensearch-nonce:1551089397451704',
                              '/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson'])
signature_hmac = hmac.new('R0OGKsMj******khMqHXBfKG'.encode('utf-8'), signature_string.encode('utf-8'), 'sha1')
signature = base64.b64encode(signature_hmac.digest())

たとえば、ユーザーの AccessKey シークレットが R0OGKsMj0*********HXBfKG であるとします。上記の計算方法を使用して計算された最終的な署名文字列は 1P7tfEh+CU5*******kkJUAMc= です。

リクエスト文字列の構築

リクエスト文字列の形式は、ホスト + CanonicalizedResource 文字列 です。

HTTP リクエストの Authorization ヘッダーに署名文字列を追加する必要があります。これは、リクエストが認証されていることを示します。HTTP リクエストには、前のセクションで説明した他の必要なヘッダーも含まれている必要があります。リクエスト文字列では、ホストは OpenSearch API のエンドポイントを指定します。

  • データ検索のリクエスト文字列:http://host/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson

  • 候補に基づいてデータを検索するリクエスト文字列:http://host/v3/openapi/apps/{appName}/suggest/{suggestName}/search?hits=10&query=%E6%A0%87%E9%A2%98

  • アプリケーションを使用してデータを検索するリクエスト文字列:http://host/v3/openapi/apps/120001234。この場合、appid を検索に使用するアプリケーションの ID(120001234 など)に置き換え、認証のために Authorization ヘッダーを指定する必要があります。リクエストパラメーターを指定する必要はありません。

  • データプッシュのリクエスト文字列:http://host/v3/openapi/apps/app_schema_demo/tab/actions/bulk。プッシュするデータは、リクエストボディに指定する必要があります。

説明

  • OpenSearch は、OpenSearch API V3 に基づいて、Java 用 SDK、PHP 用 SDK、Python 用 SDK、C# 用 SDK を提供しています。PHP 用 SDK、Python 用 SDK、C# 用 SDK は、OpenSearch API V3 の署名計算メソッドを実装しています。これらのメソッドを直接使用できます。また、PHP 用 SDK、Python 用 SDK、C# 用 SDK の署名計算のソースコードを参照して、他の言語で SDK を実装することもできます。

  • OpenSearch は、このトピックと公式 SDK のソースコードに基づいて実装された SDK を保守していません。ユーザーはこれらの SDK を自分で保守する必要があります。

アプリケーションスキーマテンプレート

{
  "name": "app_schema_demo",
  "type": "standard",
  "schema": {
    "indexes": {
      "search_fields": {
        "id": {
          "fields": [
            "id"
          ]
        },
        "name": {
          "fields": [
            "name"
          ],
          "analyzer": "chn_standard"
        },
        "phone": {
          "fields": [
            "phone"
          ],
          "analyzer": "fuzzy"
        },
        "int_arr": {
          "fields": [
            "int_arr"
          ]
        },
        "literal_arr": {
          "fields": [
            "literal_arr"
          ]
        },
        "cate_id": {
          "fields": [
            "cate_id"
          ]
        }
      },
      "filter_fields": [
        "id",
        "int_arr",
        "literal_arr",
        "float_arr",
        "cate_id"
      ]
    },
    "tables": {
      "tab": {
        "name": "tab",
        "fields": {
          "id": {
            "name": "id",
            "type": "INT",
            "primary_key": true
          },
          "name": {
            "name": "name",
            "type": "TEXT",
            "primary_key": false
          },
          "phone": {
            "name": "phone",
            "type": "SHORT_TEXT",
            "primary_key": false
          },
          "int_arr": {
            "name": "int_arr",
            "type": "INT_ARRAY",
            "primary_key": false
          },
          "literal_arr": {
            "name": "literal_arr",
            "type": "LITERAL_ARRAY",
            "primary_key": false
          },
          "float_arr": {
            "name": "float_arr",
            "type": "FLOAT_ARRAY",
            "primary_key": false
          },
          "cate_id": {
            "name": "cate_id",
            "type": "INT",
            "primary_key": false
          }
        },
        "primary_table": true
      }
    },
    "route_field": null
  },
  "data_sources": [],
  "first_ranks": {},
  "second_ranks": {},
  "summary": [],
  "fetch_fields": [
    "id",
    "name",
    "phone",
    "int_arr",
    "literal_arr",
    "float_arr",
    "cate_id"
  ],
  "quota": {
    "qps": 6,
    "doc_size": 0.3
  }
}