API Gateway Lambda オーソライザーを使用する - Amazon API Gateway

API Gateway Lambda オーソライザーを使用する

Lambda オーソライザー (以前のカスタムオーソライザー) は、Lambda 関数を使用して API へのアクセスを制御する API Gateway の機能です。

Lambda オーソライザーは、OAuth や SAML などのベアラートークン認可戦略を使用する、または発信者 ID を判断するためにリクエストパラメータを使用するカスタム認証スキームを実装する場合に便利です。

クライアントが API のメソッドの 1 つにリクエストを送信すると、API Gateway は Lambda オーソライザーを呼び出します。これは発信者 ID を入力として受け取り、IAM ポリシーを出力として返します。

Lambda オーソライザーには 2 種類あります。

  • トークンベース の Lambda オーソライザー (TOKEN オーソライザーとも呼ばれる) は、JSON ウェブトークン (JWT) や OAuth トークンなどのベアラートークンで発信者 ID を受け取ります。サンプルアプリケーションについては、GitHub の「Open Banking Brazil - Authorization Samples」を参照してください。

  • リクエストパラメータベースの Lambda オーソライザー (REQUEST オーソライザーとも呼ばれます) は、ヘッダー、クエリ文字列パラメータ、stageVariables、および $context 変数の組み合わせで発信者 ID を受け取ります。

    WebSocket API では、リクエストパラメータベースのオーソライザーのみがサポートされています。

API を作成したものとは別の AWS アカウントから AWS Lambda 関数を使用することが可能です。詳細については、「クロスアカウントの Lambda オーソライザーを設定する」を参照してください。

サンプルの Lambda 関数については、GitHub の「aws-apigateway-lambda-authorizer-blueprints」を参照してください。

Lambda オーソライザーの認証の流れ

次の図は、Lambda オーソライザーの認証の流れを示しています。


        API Gateway Lambda 認証ワークフロー
API Gateway Lambda 認証ワークフロー
  1. クライアントは、API Gateway API メソッドでメソッドを呼び出し、ベアラートークンを渡したり、パラメータを要求したりします。

  2. API Gateway は、メソッドに対して Lambda オーソライザーが設定されているかどうかを確認します。存在する場合、API Gateway は Lambda 関数を呼び出します。

  3. Lambda 関数は、次のような方法で発信者を認証します。

    • OAuth アクセストークンを取得するために OAuth プロバイダーを呼び出します。

    • SAML アサーションを取得するために SAML プロバイダーを呼び出します。

    • リクエストパラメータ値に基づいて IAM ポリシーを生成します。

    • データベースで認証情報を取得します。

  4. 呼び出しが成功すると、Lambda 関数は少なくとも IAM ポリシーとプリンシパル ID を含む出力オブジェクトを返すことによってアクセスを許可します。

  5. API Gateway はポリシーを評価します。

    • アクセスが拒否された場合、API Gateway は 403 ACCESS_DENIED などの適切な HTTP ステータスコードを返します。

    • アクセスが許可されている場合、API Gateway はメソッドを実行します。オーソライザー設定でキャッシュが有効になっている場合、API Gateway はポリシーをキャッシュするため、Lambda オーソライザー関数を再度呼び出す必要はありません。

API Gateway Lambda オーソライザーを作成するステップ

Lambda オーソライザーを作成するには、以下のタスクを実行する必要があります。

  1. Lambda コンソールで API Gateway Lambda オーソライザー関数を作成する」の説明に従って、Lambda コンソールで Lambda オーソライザー関数を作成します。設計図の例の 1 つを出発点として使用し、必要に応じて入力出力をカスタマイズできます。

  2. API Gateway コンソールを使用した Lambda オーソライザーの設定」で説明されているように、Lambda 関数を API Gateway オーソライザーとして設定し、それを必要とする API メソッドを設定します。あるいは、クロスアカウント Lambda オーソライザーが必要な場合は、「クロスアカウントの Lambda オーソライザーを設定する」を参照してください。

    注記

    AWS CLI、または AWS SDK を使用してオーソライザーを設定することもできます。

  3. API Gateway Lambda オーソライザーで API を呼び出す」の説明に従って、Postman を使用してオーソライザーをテストします。

Lambda コンソールで API Gateway Lambda オーソライザー関数を作成する

Lambda オーソライザーを作成する前に、ロジックを実装する Lambda 関数を作成して認証する必要があります。また、必要に応じて発信者を認証します。Lambda コンソールには Python の設計図が用意されています。[(設計図を使用する] を選択して [api-gateway-authorizer-python] 設計図を選択すると使用できます。それ以外の場合は、awslabs GitHub リポジトリの設計図の 1 つを開始点として使用します。

このセクションの他のサービスを呼び出さない Lambda オーソライザー関数の例では、組み込みの AWSLambdaBasicExecutionRole を使用できます。独自の API Gateway Lambda オーソライザーの Lambda 関数を作成する際に、この関数から他の AWS のサービスを呼び出す場合は、Lambda 関数に IAM 実行ロールを割り当てるよう求められます。ロールを作成するには、「AWS Lambda 実行ロール」の手順に従ってください。

その他のサンプルの Lambda 関数については、GitHub の「aws-apigateway-lambda-authorizer-blueprints」を参照してください。サンプルアプリケーションについては、GitHub の「Open Banking Brazil - Authorization Samples」を参照してください。

例: トークンベースの Lambda オーソライザー関数を作成する

トークンベースの Lambda オーソライザー関数を作成するには、Lambda コンソールに次の Node.js コードを入力し、API Gateway コンソールで次のようにテストします。

  1. Lambda コンソールで、[Create function (関数の作成)] をクリックします。

  2. [一から作成] を選択します。

  3. 関数の名前を入力します。

  4. [関数の作成] を選択します。

  5. 以下のコードをコピーしてコードエディタに貼り付けます。

    // A simple token-based authorizer example to demonstrate how to use an authorization token // to allow or deny a request. In this example, the caller named 'user' is allowed to invoke // a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke // the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty // string, the authorizer function returns an HTTP 401 status code. For any other token value, // the authorizer returns an HTTP 500 status code. // Note that token values are case-sensitive. export const handler = function(event, context, callback) { var token = event.authorizationToken; switch (token) { case 'allow': callback(null, generatePolicy('user', 'Allow', event.methodArn)); break; case 'deny': callback(null, generatePolicy('user', 'Deny', event.methodArn)); break; case 'unauthorized': callback("Unauthorized"); // Return a 401 Unauthorized response break; default: callback("Error: Invalid token"); // Return a 500 Invalid token response } }; // Help function to generate an IAM policy var generatePolicy = function(principalId, effect, resource) { var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; } // Optional output with custom properties of the String, Number or Boolean type. authResponse.context = { "stringKey": "stringval", "numberKey": 123, "booleanKey": true }; return authResponse; }
  6. [デプロイ] を選択します。

  7. まだ作成していない場合、API Gateway コンソールで簡単な API を作成します。

  8. API リストから API を選択します。

  9. [Authorizers (オーソライザー)] を選択します。

  10. [新しいオーソライザーの作成] を選択します。

  11. オーソライザーの名前を入力します。

  12. [タイプ] で [Lambda] を選択します。

  13. [Lambda 関数] で、Lambda オーソライザー関数を作成したリージョンを選択し、ドロップダウンリストで関数名を選択します。

  14. [Lambda 呼び出しロール] は空白のままにします。

  15. [Lambda イベントペイロード] の場合は、[トークン] を選択します。

  16. [Token Source (トークンのソース)] に「authorizationToken」と入力します。

  17. [Create (作成)] を選択し、[Grant & Create (付与 & 作成)] を選択します。

  18. [Test (テスト)] を選択します。

  19. authorizationToken の値として「allow」と入力します。

  20. [Test (テスト)] を選択します。

この例では、API がメソッドリクエストを受信すると、API Gateway は event.authorizationToken 属性でこの Lambda オーソライザー関数にソーストークンを渡します。Lambda オーソライザー関数はトークンを読み取り、次のように動作します。

  • トークン値が 'allow' の場合、オーソライザー関数のテストは 200 OK HTTP レスポンスと次のような IAM ポリシーを返し、メソッドリクエストは成功します。

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
  • トークン値が 'deny' の場合、オーソライザー関数のテストは 200 OK HTTP レスポンスと次のような Deny IAM ポリシーを返し、メソッドリクエストは失敗します。

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Deny", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
    注記

    テスト環境以外ではオーソライザー関数は 403 Forbidden HTTP レスポンスを返し、メソッドリクエストは失敗します。

  • トークン値が 'unauthorized' または空の文字列の場合、オーソライザー関数のテストは 401 Unauthorized HTTP レスポンスを返し、メソッド呼び出しは失敗します。

  • それ以外のトークンの場合、クライアントは 500 Invalid token レスポンスを受け取り、メソッド呼び出しは失敗します。

注記

本番稼働コードでは、権限を付与する前にユーザーの認証が必要になる場合があります。その場合は、そのプロバイダーのドキュメントの指示に従って認証プロバイダーを呼び出すことで、Lambda 関数に認証ロジックを追加できます。

Lambda オーソライザー関数は、IAM ポリシーだけでなく、発信者のプリンシパル ID を返す必要があります。オプションで、context オブジェクトを返すこともできます。これには、統合バックエンドに渡すことができる追加情報が含まれます。詳細については、「Amazon API Gateway Lambda オーソライザーからの出力」を参照してください。

例: リクエストベースの Lambda オーソライザー関数を作成する

リクエストベースの Lambda オーソライザー関数を作成するには、Lambda コンソールに次の Node.js コードを入力し、API Gateway コンソールで次のようにテストします。

  1. Lambda コンソールで、[Create function (関数の作成)] をクリックします。

  2. [一から作成] を選択します。

  3. 関数の名前を入力します。

  4. [関数の作成] を選択します。

  5. 以下のコードをコピーしてコードエディタに貼り付けます。

    export const handler = function(event, context, callback) { console.log('Received event:', JSON.stringify(event, null, 2)); // A simple request-based authorizer example to demonstrate how to use request // parameters to allow or deny a request. In this example, a request is // authorized if the client-supplied headerauth1 header, QueryString1 // query parameter, and stage variable of StageVar1 all match // specified values of 'headerValue1', 'queryValue1', and 'stageValue1', // respectively. // Retrieve request parameters from the Lambda function input: var headers = event.headers; var queryStringParameters = event.queryStringParameters; var pathParameters = event.pathParameters; var stageVariables = event.stageVariables; // Parse the input for the parameter values var tmp = event.methodArn.split(':'); var apiGatewayArnTmp = tmp[5].split('/'); var awsAccountId = tmp[4]; var region = tmp[3]; var restApiId = apiGatewayArnTmp[0]; var stage = apiGatewayArnTmp[1]; var method = apiGatewayArnTmp[2]; var resource = '/'; // root resource if (apiGatewayArnTmp[3]) { resource += apiGatewayArnTmp[3]; } // Perform authorization to return the Allow policy for correct parameters and // the 'Unauthorized' error, otherwise. var authResponse = {}; var condition = {}; condition.IpAddress = {}; if (headers.headerauth1 === "headerValue1" && queryStringParameters.QueryString1 === "queryValue1" && stageVariables.StageVar1 === "stageValue1") { callback(null, generateAllow('me', event.methodArn)); } else { callback("Unauthorized"); } } // Help function to generate an IAM policy var generatePolicy = function(principalId, effect, resource) { // Required output: var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; // default version policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; // default action statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; } // Optional output with custom properties of the String, Number or Boolean type. authResponse.context = { "stringKey": "stringval", "numberKey": 123, "booleanKey": true }; return authResponse; } var generateAllow = function(principalId, resource) { return generatePolicy(principalId, 'Allow', resource); } var generateDeny = function(principalId, resource) { return generatePolicy(principalId, 'Deny', resource); }
  6. [デプロイ] を選択します。

  7. まだ作成していない場合、API Gateway コンソールで簡単な API を作成します。

  8. API リストから API を選択します。

  9. [Authorizers (オーソライザー)] を選択します。

  10. [新しいオーソライザーの作成] を選択します。

  11. オーソライザーの名前を入力します。

  12. [タイプ] で [Lambda] を選択します。

  13. [Lambda 関数] で、Lambda オーソライザー関数を作成したリージョンを選択し、ドロップダウンリストで関数名を選択します。

  14. [Lambda 呼び出しロール] は空白のままにします。

  15. [Lambda イベントペイロード] の場合は、[リクエスト] を選択します。

  16. [ID ソース] の下に、headerauth1 という [ヘッダー]、QueryString1 という [クエリ文字列]、および StageVar1 という [ステージ変数] を追加します。

  17. [Create (作成)] を選択し、[Grant & Create (付与 & 作成)] を選択します。

  18. [Test (テスト)] を選択します。

  19. [headerauth1] に、headerValue1 と入力します。[QueryString1] に、queryValue1 と入力します。[StageVar1] に、stageValue1 と入力します。

  20. [Test (テスト)] を選択します。

この例では、Lambda オーソライザー関数は入力パラメータをチェックして次のように動作します。

  • 必要なすべてのパラメータ値が予想値と一致する場合、オーソライザー関数は 200 OK HTTP レスポンスと次のような IAM ポリシーを返し、メソッドリクエストは成功します。

    { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/" } ] }
  • そうでない場合、オーソライザー関数は 401 Unauthorized HTTP レスポンスを返し、メソッド呼び出しは失敗します。

注記

本番稼働コードでは、権限を付与する前にユーザーの認証が必要になる場合があります。その場合は、そのプロバイダーのドキュメントの指示に従って認証プロバイダーを呼び出すことで、Lambda 関数に認証ロジックを追加できます。

Lambda オーソライザー関数は、IAM ポリシーだけでなく、発信者のプリンシパル ID を返す必要があります。オプションで、context オブジェクトを返すこともできます。これには、統合バックエンドに渡すことができる追加情報が含まれます。詳細については、「Amazon API Gateway Lambda オーソライザーからの出力」を参照してください。