

# WebSocket ライブラリで署名済みリクエストを生成する
<a name="network-analyzer-generate-request"></a>

WebSocket ライブラリを使用してサービスにリクエストを送信できるように、署名済みリクエストを生成する方法を次に示します。

## IAM ロールに WebSocket リクエストのポリシーを追加する
<a name="network-analyzer-iam"></a>

WebSocket プロトコルを使用してネットワークアナライザを呼び出すには、リクエストを行う AWS Identity and Access Management (IAM) ロールに以下のポリシーをアタッチする必要があります。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iotwireless:StartNetworkAnalyzerStream",
            "Resource": "*"
        }
    ]
}
```

## 署名付き URL を作成する
<a name="network-analyzer-presigned-url"></a>

アプリケーションとネットワークアナライザとの間の通信を設定するために必要な情報を含む、WebSocket リクエストの URL を作成します。リクエストのアイデンティティを確認するために、WebSocket ストリーミングでは、署名のリクエストに Amazon 署名バージョン 4 のプロセスが使用されます。署名バージョン 4 の詳細については、*Amazon Web Services 全般のリファレンス*の「[AWS API リクエストの署名](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)」を参照してください。

ネットワークアナライザを呼び出すには、`StartNetworkAnalyzerStream` リクエスト URL を使用します。リクエストは、前述の IAM ロールの認証情報を使用して署名されます。URL は以下の形式です。読みやすさのために改行が追加されています。

```
GET wss://api.iotwireless.<region>.amazonaws.com/start-network-analyzer-stream?X-Amz-Algorithm=AWS4-HMAC-SHA256
   &X-Amz-Credential=Signature Version 4 credential scope
   &X-Amz-Date=date
   &X-Amz-Expires=time in seconds until expiration
   &X-Amz-Security-Token=security-token
   &X-Amz-Signature=Signature Version 4 signature 
   &X-Amz-SignedHeaders=host
```

署名バージョン 4 パラメータには、次の値を使用します。
+ **X-Amz-Algorithm** – 署名プロセスに使用しているアルゴリズム。唯一の有効な値は `AWS4-HMAC-SHA256` です。
+ **X-Amz-Credential** – アクセスキー ID と認証情報スコープのコンポーネントを連結して形成され、スラッシュ (/) で区切られる文字列。認証情報スコープには、YYYYMMDD 形式の日付、AWS リージョン、サービス名、および終了文字列 (aws4\$1request) が含まれます。
+ **X-Amz-Date** – 署名が作成された日時。*Amazon Web Services 全般リファレンス*の「[署名バージョン 4 の日付の処理](https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html)」の手順に従って、日付と時刻を生成します。
+ **X-Amz-Expires** – 認証情報が有効期限切れになるまでの時間 (秒単位)。最大値は 300 秒 (5 分) です。
+ **X-Amz-Security-Token** – (オプション) 一時的な認証情報用の署名バージョン 4 のトークン。このパラメータを指定する場合は、正規リクエストに含めます。詳細については、*AWS Identity and Access Management ユーザーガイド*の「[一時的なセキュリティ認証情報のリクエスト](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)」を参照してください。
+ **X-Amz-Signature** – リクエストに対して生成した署名バージョン 4 の署名。
+ **X-Amz-SignedHeaders** – リクエストの署名を作成するときに署名されるヘッダー。唯一の有効な値は `host` です。

## リクエスト URL を構築し、署名バージョン 4 署名を作成する
<a name="connect-iot-network-analyzer-construct-url-sign"></a>

リクエストの URL を作成し、署名バージョン 4 の署名を作成するには、次のステップを実行します。例は擬似コードで示しています。

### タスク 1: 正規リクエストを作成する
<a name="canonical-request"></a>

リクエストからの情報を含む文字列を標準化された形式で作成します。これにより、AWS は、リクエストを受け取ると、[タスク 3: 署名を計算する](#calculate-signature) でお客様が計算したものと同じ署名を計算できるようになります。詳細については、*Amazon Web Services 全般のリファレンス*の「[署名バージョン 4 の正規リクエストを作成する](https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html)」を参照してください。

1. アプリケーションでリクエストの変数を定義します。

   ```
   # HTTP verb
   method = "GET"
   # Service name
   service = "iotwireless"
   # AWS リージョン
   region = "AWS リージョン"
   # Service streaming endpoint
   endpoint = "wss://api.iotwireless.region.amazonaws.com"
   # Host
   host = "api.iotwireless.<region>.amazonaws.com"
   # Date and time of request
   amz-date = YYYYMMDD'T'HHMMSS'Z'
   # Date without time for credential scope
   datestamp = YYYYMMDD
   ```

1. 正規 URI (ユニフォームリソース識別子) を作成します。正規 URI はドメインとクエリ文字列との間の URI の一部です。

   ```
   canonical_uri = "/start-network-analyzer-stream"
   ```

1. 正規ヘッダーと署名付きヘッダーを作成します。正規ヘッダーの末尾の `\n` に注意してください。
   + 小文字のヘッダー名とそれに続くコロンを追加します。
   + このヘッダーの値のカンマ区切りリストを追加します。複数の値を持つヘッダーの値はソートしないようにします。
   + 改行 (`\n`) を追加します。

   ```
   canonical_headers = "host:" + host + "\n"
   signed_headers = "host"
   ```

1. アルゴリズムをハッシュアルゴリズムに一致させます。SHA-256 を使用する必要があります｡

   ```
   algorithm = "AWS4-HMAC-SHA256"
   ```

1. 派生キーの範囲をリクエストが実行された日付、 リージョン、サービスに絞るための認証情報スコープを作成します。

   ```
   credential_scope = datestamp + "/" + region + "/" + service + "/" + "aws4_request"
   ```

1. 正規クエリ文字列を作成します。クエリ文字列値は、URI エンコードされ、名前順にソートされている必要があります。
   + パラメータ名を文字コードポイントで昇順にソートします。名前が重複しているパラメータは、値でソートする必要があります。たとえば、大文字 F で始まるパラメータ名は、小文字 b で始まるパラメータ名より前に置きます。
   + [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) が定義する非予約文字である A-Z、a-z、0-9、ハイフン (-)、アンダースコア (\$1)、ピリオド (.)、およびチルド (\$1) を、URI でエンコードしないようにします。
   + 他のすべての文字についても、%XY によるパーセントエンコードが必要です。X および Y には 16 進数文字 (0～9 および大文字の A ～ F) が入ります。例えば、スペース文字は %20 として (一部のエンコードスキームのように '\$1' を使用せずに) エンコードする必要があり、拡張 UTF-8 文字は %XY%ZA%BC 形式でエンコードする必要があります。
   + パラメータ値の等号 (=) 文字を二重エンコードします。

   ```
   canonical_querystring  = "X-Amz-Algorithm=" + algorithm
   canonical_querystring += "&X-Amz-Credential="+ URI-encode(access key + "/" + credential_scope)
   canonical_querystring += "&X-Amz-Date=" + amz_date 
   canonical_querystring += "&X-Amz-Expires=300"
   canonical_querystring += "&X-Amz-Security-Token=" + token
   canonical_querystring += "&X-Amz-SignedHeaders=" + signed_headers
   canonical_querystring += "&language-code=en-US&media-encoding=pcm&sample-rate=16000"
   ```

1. ペイロードのハッシュを作成します。GET リクエストの場合、ペイロードは空の文字列です。

   ```
   payload_hash = HashSHA256(("").Encode("utf-8")).HexDigest()
   ```

1. すべての要素を組み合わせて正規リクエストを作成します。

   ```
   canonical_request = method + '\n' 
      + canonical_uri + '\n' 
      + canonical_querystring + '\n' 
      + canonical_headers + '\n' 
      + signed_headers + '\n' 
      + payload_hash
   ```

### タスク 2: 署名する文字列を作成します。
<a name="create-urlsign"></a>

署名する文字列には、リクエストについてのメタ情報が含まれています。次のステップでリクエストの署名を計算するときに、文字列を使用してサインインします。詳細については、*Amazon Web Services 全般のリファレンス*の「[署名バージョン 4 の署名文字列を作成する](https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html)」を参照してください。

```
string_to_sign=algorithm + "\n"
   + amz_date + "\n"
   + credential_scope + "\n"
   + HashSHA256(canonical_request.Encode("utf-8")).HexDigest()
```

### タスク 3: 署名を計算する
<a name="calculate-signature"></a>

AWS シークレットアクセスキーから署名キーを取得します。保護レベルを高めるために、派生キーは日付、サービス、AWS リージョンに固有になっています。取得したキーを使用して、リクエストに署名します。詳細については、*Amazon Web Services 全般のリファレンス*の「[AWS 署名バージョン 4 の署名を計算する](https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html)」を参照してください。

コードでは、`GetSignatureKey` 関数を実装して署名キーを取得したものとします。詳細と関数の例については、「*Amazon Web Services 全般リファレンス*」の「[署名バージョン 4 の署名キーを取得する方法の例](https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html)」を参照してください。

関数 `HMAC(key, data)` は、バイナリ形式で結果を返す HMAC-SHA 256 関数を表します。

```
#Create the signing key
signing_key = GetSignatureKey(secret_key, datestamp, region, service)
                
# Sign the string_to_sign using the signing key
signature = HMAC.new(signing_key, (string_to_sign).Encode("utf-8"), Sha256()).HexDigest
```

### タスク 4: 署名情報をリクエストに追加し、リクエスト URL を作成する
<a name="sign-request"></a>

署名を計算したら、クエリ文字列に追加します。詳細については、*Amazon Web Services 全般リファレンス*の「[HTTP リクエストに署名を追加する](https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html)」を参照してください。

```
#Add the authentication information to the query string
canonical_querystring += "&X-Amz-Signature=" + signature
                
# Sign the string_to_sign using the signing key
request_url = endpoint + canonical_uri + "?" + canonical_querystring
```

## 次のステップ
<a name="network-analyzer-request-next"></a>

WebSocket ライブラリでリクエスト URL を使用して、サービスへのリクエストを実行し、メッセージを確認できるようになりました。詳細については、「[WebSocket メッセージとステータスコード](network-analyer-messages-status.md)」を参照してください。