Auth0 カスタムオーソライザーを使用してAWS API Gateway Endpointへセキュアにアクセスする (1/2)

#はじめに
このブログは、Auth0の[Secure AWS API Gateway Endpoints Using Custom Authorizer](https://auth0.com/docs/integrations/aws-api-gateway/custom-authorizers)を日本語化したものです(英語版のPart 1 およびPart 2の内容です)。

AWSを使用すると、[Lambda](https://aws.amazon.com/lambda/)、[API Gateway](https://aws.amazon.com/api-gateway/)、およびJavaScriptクライアントをフロントエンドに使用した、強力でServerless でスケーラビリティの高いAPIとアプリケーションを作成することができます。

Serverless アプリケーションは、カスタムコードをコンピューティングサービスとして実行し、サービスをホストするオペレーティング環境を維持する必要はありません。 代わりに、[AWS Lambda](https://aws.amazon.com/lambda/)や[webtask.io](https://webtask.io/)のようなサービスがあなたの代わりにコードを実行します。

API Gatewayは、Lambda ファンクションの前段にサービスレイヤーを追加し、セキュリティを拡張し、入力/出力時のメッセージ変換を管理し、スロットリングや監査等の機能を提供することで、Lambdaの機能を拡張します。 Serverless アプローチは、スケールアウトやフォールトトレランスのような懸念事項がコードを実行するコンピューティングサービスの責任になるため、運用上の要求事項を簡素化されます。

このチュートリアルでは、APIゲートウェイを使用してAPIを設定方法、Lamdba ファンクション （カスタムオーソライザを含む）の作成、および設定してAPIエンドポイントを保護し、ユーザーがAPIにアクセスするために必要なAccess TokenをAuth0から取得できるための認可フローを実装する方法を説明します。 

より具体的には、カスタムオーソライザーは:

1. APIに対するアクセスに対するリクエストの`authorization`ヘッダーを介してAccess Tokenがパスされたことを確認します
2. [JWKSエンドポイント](https://auth0.com/docs/jwks)経由で取得した公開鍵を使用し、Access Tokenの[RS256署名](https://auth0.com/docs/apis#signing-algorithms)を検証します
3. Access Tokenに必要なIssuer `iss` および Audience `aud` Claim情報があることを確認します

OAuth 2.0は初めてですか? [OAuth 2.0の紹介](https://auth0.com/docs/protocols/oauth2)をご覧ください。

さて、このチュートリアルでは、以下のセクションに分けて解説をしています。

1章 - Auth0 を設定する
2章 - AWS API Gateway のセットアップおよび導入
3章 - カスタムオーソライザー の作成
4章 - カスタムオーソライザーを使用してAPIを保護する

##API Gatewayカスタムオーソライザーの動作
[Amazonによると](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/use-custom-authorizer.html)、API Gatewayカスタムオーソライザーは、「OAuthやSAMLなどのベアラートークン認証方法を使用して、APIへのアクセス制御を提供するLambda関数制御を提供するLambda関数」です。

どのような場合でも誰か(もしくはプログラム)がAPIを呼び出す際には、API GatewayはAPIにカスタムオーソライザーが設定してあるかどうかをチェックします。

APIにカスタムオーソライザーが設定されている場合には、API Gatewayはカスタムオーソライザーを呼び出し、受信したリクエストヘッダーから抽出したAuthorizationトークンを提供します。

カスタムオーソライザーは[JWT](https://auth0.com/docs/jwt)の検証、リクエストを認可するIAMポリシーなど、異なるタイプの認可ストラテジで実装することができます。もしポリシーが無効、もしくは承認されなかった場合には、APIコールは失敗します。

有効なポリシーの場合、APIは返されたポリシーをキャッシュし、それを受信したトークンに関連付けし、現在および将来の要求に使用します。ポリシーをキャッシュをする時間は設定可能です。デフォルトは`300`秒、最大キャッシュ時間は`3600`秒です(値に0を設定することでキャッシュを無効化することもできます)。

##はじめる前に
このチュートリアルを始める前に、AWSアカウントで[AWSにサインアップ](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html?nc2=h_ct)する必要があります。これにより、このチュートリアルで使用するAWSのすべての機能 (API GatewayやLambdaなど)にアクセスできます。新規登録メンバーはAWSに１２ヶ月間無償でアクセスすることができます。

##参考文献
[API認可 (API Authorization)](https://auth0.com/docs/api-auth)
[Auth0 Access Tokenを取得する](https://auth0.com/docs/tokens/access-token#how-to-get-an-access-token)
[JSON Web Key Sets (JWKS)](https://auth0.com/docs/jwks)

#1. Auth0 にAPIを登録する
正常に認可されたクライアントが使用するAPIを構成する必要があります。[Auth0 管理DashboardのAPIsセクション](https://manage.auth0.com/#/apis)から構成することができます。

**CREATE API** をクリックして、連携のための新しいAPIを作成します。

![api-1.png](https://qiita-image-store.s3.amazonaws.com/0/189613/06deb6f8-2566-1cf9-6137-263039169798.png)

以下の項目に対して、値の入力を求められます:

|パラメーター|値|
|:---|:---|
|Name|APIに対するわかりやすい名称。この値はAuth0 APIs画面でリスト表示されます|
|Identifier|APIの論理識別子 (この識別子のフォーマットにはURL https://your-api-gateway のように定義することを推奨します)|
|Signing Algorithm|発行されたAccess Tokenを署名する際にAuth0が使用するアルゴリズム|

**CREATE** をクリックして、次に進みます.

![api-2.png](https://qiita-image-store.s3.amazonaws.com/0/189613/d5f6760a-647e-3dcd-9330-f002baaab0d8.png)

新しく作成したAPIの詳細については、**Setting** ページを参照してください。


![api-3.png](https://qiita-image-store.s3.amazonaws.com/0/189613/a63ba68e-7a12-c596-61df-eb3b9fb011fa.png)

APIを作成すると、APIで使用するためのNon Interactive Clientも作成されます。このクライアントは、API設定のNon Interactive Clientsタブで **Authorized** とリスト表示されます。さらにこのチュートリアルの３章で必要となるため、Client IDを書き留めておいてください。

#2. API Gateway APIのインポートおよび導入

`チュートリアルのこの章については、AWSの公式例を基に作成されています。`詳しくは[こちら]をご参照下さい。

AWS API Gatewayチュートリアルを行うこの章では、API Gatewayを使用して、以下のようなAPIのインポート方法および管理方法を紹介いたします:

・API GatewayにAPIをインポートする
・ImportしたAPIのテスト
・どのようなフロントエンド・クライアントでも使用できるAPIのデプロイ
・デプロイしたAPIのテスト

このチュートリアルの後半で、Auth0 Access Tokenを受理したカスタムオーソライザーを使用してAPIのエンドポイントをそのようにセキュアにするか、同様にAPIをフロントエンドJavascriptクライアントに統合するかを説明いたします。

##Pets APIのインポートおよび構成
AWSアカウントでAWSにログインし、トップナビゲーションバーにある**サービス**ドロップダウンメニューを使用して、**API Gateway**コンソールに移動します。

以前APIを作成したことがある場合は、単にAPI Gatewayコンソールが表示されるので、**APIの作成**をクリックし、**APIの例**を選択します。

まだAPI Gatewayを使用してAPIを作成したことがない場合には、以下の画面が表示されます。**今すぐ始める**をクリックして次に進みます。

![スクリーンショット 2018-03-01 16.16.58.png](https://qiita-image-store.s3.amazonaws.com/0/189613/9489f7ec-12c9-f1cb-81b8-20e64cd57aa4.png)

「Amazon API Gatewayへようこそ。...」というポップアップメッセージが表示されます。**OK**をクリックして次に進みます。

![スクリーンショット 2018-03-01 16.21.34.png](https://qiita-image-store.s3.amazonaws.com/0/189613/f7dc3cb9-6787-db61-1754-8b47a7178b69.png)


新しいAPIの作成フォームで、デフォルト**APIの例**が選択されており、エディターにサンプルAPIが定義されていると思います。これからのチュートリアルではこのAPIを使用します。**インポート**をクリックしてAPIを作成します。

![スクリーンショット 2018-03-01 16.23.27.png](https://qiita-image-store.s3.amazonaws.com/0/189613/8bcd7dfb-dde9-f3a7-896a-c67d1a144eec.png)

作成が完了すると、AWSにAPIが作成され、提供されたデータが入力されたことを示すメッセージが表示されます。

![スクリーンショット 2018-03-01 16.25.01.png](https://qiita-image-store.s3.amazonaws.com/0/189613/8d9d325b-24dc-94ae-3e0e-26f30c062328.png)

APIにはすでに関連したメソッドが存在することに注意して下さい(つまり`GET`と`POST`)。リソースツリーからメソッド名をクリックすることで、メソッドの詳細を表示したり、設定の変更をしたり、メソッドの呼び出しをテストすることができます。

![スクリーンショット 2018-03-01 16.26.22.png](https://qiita-image-store.s3.amazonaws.com/0/189613/6a9c624d-1957-c33e-cf01-d536f8a38626.png)

###APIをテストする
APIを正常にインポートできたので、全てが期待通りに動作するかを確認するために、いくつかテストを実行してみましょう。この演習では、API自体のいくつかの機能についても説明します。

例として、`/pets`配下の**POST**をクリックします。`POST`メソッドの構造と振る舞いの概要を示、**メソッドの実行**ウィンドウが表示されます。

**メソッドリクエストとメソッドレスポンス**: フロントエンドとのAPIインターフェース
**統合リクエストと統合レスポンス**: バックエンドとのAPIインターフェース

この領域を使用して、作成したAPIをテストできます。

**テスト**をクリックします(ページ中央にある、細長い**クラアント**領域にあります)。

![スクリーンショット 2018-03-01 16.28.37.png](https://qiita-image-store.s3.amazonaws.com/0/189613/2b15e88b-c45f-a606-2116-4f08b413ac17.png)

`/pets - POST - メソッドテスト` ページにリダイレクトされます。

![スクリーンショット 2018-03-01 16.30.51.png](https://qiita-image-store.s3.amazonaws.com/0/189613/2932c32c-0b89-d3bd-2dc7-94a13ac15ff0.png)


画面を底部までスクロールし、**リクエスト本文**に以下の文字列を入力します:

```json
{"type": "dog", "price": 249.99}
```

リクエスト本文はデータベースに追加したいペットの属性、およびペットの価格を示しています。

![スクリーンショット 2018-03-01 16.32.47.png](https://qiita-image-store.s3.amazonaws.com/0/189613/2eadf48a-3c66-e6ae-21e2-228ac2640ebd.png)

**テスト**をクリックします。

テスト結果はページの右側に表示されます。

![スクリーンショット 2018-03-01 17.40.04.png](https://qiita-image-store.s3.amazonaws.com/0/189613/ac9a29c7-d597-809b-5203-709b5e032fd6.png)


###APIをデプロイする
上記で完了したテストは、API Gatewayコンソールを使用して実行しました。異なるクライアントでAPIを使用するためには、APIをステージ環境にデプロイする必要があります。これは**アクション**メニューの**APIのデプロイ**オプションから実行することができます。

以下のパラメーターについて入力を求められます:

|パラメーター|値|
|:---|:---|
|デプロイされるステージ|**[新しいステージ]**を選択|
|ステージ名|ステージの名称を入力します|
|ステージの説明|ステージの説明を入力します|
|デプロイメントの説明|APIデプロイメントの説明を入力します|

適切な値の入力が完了したら**デプロイ**をクリックします。

![スクリーンショット 2018-03-01 17.43.41.png](https://qiita-image-store.s3.amazonaws.com/0/189613/3fbaf318-b46a-2686-9ec3-502c38be556b.png)

###デプロイメントのテスト
APIが正常にデプロイされると、**Testステージエディター**にリダイレクトされます。ここでAPIが正常にデプロイできたかどうかをテストすることができます。

**Testステージエディター**の一番上にある青いバナーに**URL の呼び出し**が表示されています。これはAPIの`GET`エンドポイントを呼び出すためのURLです。

![スクリーンショット 2018-03-01 17.44.38.png](https://qiita-image-store.s3.amazonaws.com/0/189613/d1d46927-ed5f-7aae-c48b-7525519eadb6.png)

`GET /`メソッドリクエスト画面に表示されたURLをクリックします。すると以下のようなレスポンスが表示されるはずです:

![aws-pt1-8.png](https://qiita-image-store.s3.amazonaws.com/0/189613/2f71347f-520c-c33b-0c20-f511b22eee12.png)

次に、`/pets/{petId}`の**GET**メソッドをコールします。**ステージ**ページで**Test**ツリーを展開して下さい。

![スクリーンショット 2018-03-01 22.05.09.png](https://qiita-image-store.s3.amazonaws.com/0/189613/6c9ff4f7-79c4-df2c-4806-e5e35a317d95.png)

画面の一番上の青いバナーに**URL の呼び出し**が表示されています。最後の部分{pedID}はパス変数を表しています。この変数を1に置き換え、ブラウザを使用して新しいURLにアクセスします。次のJSONペイロードでHTTP 200リクエストを受信するはずです:

```json
{
  "id": 1,
  "type": "dog",
  "price": 249.99
}
```
![スクリーンショット 2018-03-01 22.07.52.png](https://qiita-image-store.s3.amazonaws.com/0/189613/9b70d766-76f9-68fa-8eae-183ad4d27afe.png)

###第２章のまとめ
AWS API Gatewayチュートリアルの第２章では、以下の内容をカバーしました:

・API GatewayにAPIをインポートする
・インポートしたAPIのテスト
・どのようなフロントエンド・クライアントでも使用できるAPIのデプロイ
・デプロイしたAPIのテスト

これでAPI Gatewayによって管理された完全に機能するAPIが完成しました。


###[パート２(2/2)](https://qiita.com/furuth/items/a4404f2873c2443a3666)に続きます。
パート２では、以下の項目について説明をします。
3章 - Auth0 カスタムオーソライザーの作成
4章 - カスタムオーソライザーを使用してAPIを保護する

###[パート２へ行く](https://qiita.com/furuth/items/a4404f2873c2443a3666)###