AWS API Gatewayチュートリアルの手順5

手順5 - IDフローにIDトークンを使用する

この最後の手順では以下を行います。

  • OpenIDJSON Web Token(JWT)を渡して、サービスへIDを送る

  • トークンを検証する

  • プロファイル情報を抽出して、ペットの購入者を割り当てる

IDトークンを使用する

ユーザーに関する情報の処理や取得には、Lambda関数を使用することができます。たとえば、購入トランザクション中に、IDトークンで返されたプロファイルからユーザー名を取得したとします。その際に、JSON Web Token(JWT)であるID自体に埋め込まれたユーザーの情報も取得することができます。

JWTの使用する利点は、以下を行えることです。

  1. JWTの真正性を検証する

  2. 呼び出しを行っているユーザーが認証されることを確実にする(改ざんの可能性があるプレーンテキストのパラメーターに依存しない)

その他にも、認可にJWTを使用して、Amazon API GatewayとのIAM統合を迂回することができます。認可にAPI Gatewayを使用すると、Lambda関数を呼び出す前にAPIの呼び出しを止められることに注意してください。

JWTに情報を追加する

JWTにユーザー情報を追加するには、いくつかの方法があります。以下の例では、ユーザーのメールアドレスをJWTに追加していますが、概念は他のユーザーのデータポイントについても同じです。

ルールを使用する

ユーザーのメールアドレスをJWTに追加する方法の1つが、ルールです。この方法は、値がユーザー認証用のJWTで常に利用可能なことを確実にしたい場合には適切です。

login.jsでは、auth.signinに渡されるパラメーターにこのスコープが指定されているのを確認できます。

$scope.login = function() {
    var params = {
        authParams: {
          scope: 'openid email'
        }
      };

    auth.signin(params, function(profile, token) {
      ...
    }
  }

Was this helpful?

/

JWTにはユーザーのプロファイル全体を含めることもできますが、JWTは通常すべての要求で渡されるため、必要なものだけを含めるようにします。

JWTトークンを検証する

AWS Lambdaコンソールは、ブラウザーコンソールでNode.jsコードを入力する際に、限られた数のノードモジュールにのみアクセスするため、IDトークンを処理するパッケージとして追加でモジュールをインクルードして、Lambda関数をアップロードする必要があります。

詳細については、「Node.jsを使って導入パッケージを作成する」と「導入パッケージをアップロードしてテストする」をご覧ください。

以下のシードプロジェクトには、更新されたAWS Lambda関数に必要なコードが含まれています。

<%= include('../../../_includes/_package', { org: 'auth0', repo: 'auth0-aws', path: 'examples/api-gateway/lambda' }) %>

シードプロジェクト内には、以下の2つのカスタムJavaScriptファイルがあります。

  • index.js:メインコードが含まれています。

  • auth0-variables:更新する必要のあるコードが含まれています。

カスタムファイルに加えて、Node.jsに標準のpackage.jsonファイルがあります。

コードは、JWTから情報を抽出して、JWTを検証するために機能性を追加します。Auth0はデフォルトで対称キーを使用しますが、非対称キーの使用を選ぶこともできます(サードパーティがトークンを検証可能にする必要がある場合には、非対称キーを使用して、公開鍵だけを共有します)。

トークン検証の詳細については、「Auth0が対応しているIDプロトコル」をご覧ください。

秘密鍵でauth0-variables.jsを更新します。秘密鍵は、Auth0 Dashboardにある[Application(アプリケーション)]の[Settings(設定)]タブに表示されます。

var env={};
env.AUTH0_SECRET='{yourAuth0Secret}';
module.exports = env;

Was this helpful?

/

ファイルのあるディレクトリからnpm installを実行して、内容をZIP形式で圧縮し(index.jsは必ずZIPのルート)、Lambda関数のPurchasePetが使えるようにアップロードします。これをテストすると、JWTがメッセージの本文にないため、認証が失敗します。

index.jsでロジックを確認します。60行目辺りのロジックではトークンが検証して解読され、購入ロジックで使われるID情報が含まれた、デコードされた情報が抽出されています。

if(event.authToken) {
     jwt.verify(event.authToken, secret, function(err, decoded) {
         if(err) {
           console.log('failed jwt verify: ', err, 'auth: ', event.authToken);
           context.done('authorization failure', null);
         } else if(!decoded.email)
         {
           console.log('err, email missing in jwt', 'jwt: ', decoded);
           context.done('authorization failure', null);
         } else {
           userEmail = decoded.email;
           console.log('authorized, petId', petId, 'userEmail:', userEmail);
           dynamo.getItem({TableName:"Pets", Key:{username:"default"}}, readcb);
         }
     });
  } else {
     console.log('invalid authorization token', event.authToken);
     context.done('authorization failure', null);
  }
    ...

Was this helpful?

/

プロファイル情報を抽出して購入者を割り当てる

最後の手順では、JWTをブラウザーのクライアントが使用するメソッドに渡します。

標準のメソッドにはAuthorizationヘッダーがBearerトークンとして含まれており、このメソッドを使用するには、IAM認証を無効にして、認証にOpenIDのトークンだけを使用する必要があります(AWS Lambda関数に渡すイベントデータにAuthorizationヘッダーをマッピングすることも必要です)。

ところが、IAMを使用している場合、AWS API GatewayはAuthorizationヘッダーにメッセージの署名を含んでいるため、このヘッダーにJWTを書き込むと認証が破壊されます。これは以下のいずれかの方法で対処します。

  • JWTのためにカスタムヘッダーを追加する

  • メッセージの本文にカスタムヘッダーを入れる

カスタムヘッダーの使用を選んだ場合には、pets/purchaseのPOSTメソッドの統合要求に何らかのマッピングを行う必要があります。

検証プロセスを続けるために、AWS Lambda関数へのPOSTの本文でJWTを渡します。これを行うには、以下のように、本文からuserNameを削除して、authTokenを追加することで、home.jsbuyPetメソッドを更新します。

function buyPet(user, id) {
    var apigClient = getSecureApiClient();
    var body = {
      petId:id,
      authToken: store.get('token')
    };

    apigClient.petsPurchasePost({}, body)
      .then(function(response) {
        console.log(response);
        $scope.pets = response.data;
        $scope.$apply();
      }).catch(function (response) {
        alert('buy pets failed');
        showError(response);
    });
}

Was this helpful?

/

S3のバケットにコードをアップロードして、ペットを購入しようとしてみてください。出力のメッセージに購入者のメールアドレスが表示されているはずです。

エラーがあった場合には、秘密鍵を正しく設定したことを確認してください。トークンのデコードの問題を確認する便利なツールの1つが、jwt.ioです。

Summary(概要)

このチュートリアルでは、以下について説明されています。

  • AWS Lamdba関数を用いたメソッドなど、AWS API Gatewayを使ってAPIを作成する

  • IAMロールを使ってAPIへのアクセスを保護する

  • APIへのアクセスをユーザーベースと結び付けて、SAML IDプロバイダーとIAMを統合する

  • ユーザーがデータベース接続か、ソーシャル接続かを基にして、異なるレベルのアクセスを提供する

  • Auth0を使ってロールの割り当てを強制する

  • JWTを使ってより細かな認証コンテキストを提供し、ID情報を適切なLambda関数に渡す