メニュー
Amazon API Gateway
開発者ガイド

API Gateway Lambda オーソライザーの使用

Amazon API Gateway Lambda オーソライザー (以前のカスタムオーソライザー) は、API メソッドへのアクセスを制御するために使用する Lambda 関数です。Lambda オーソライザーでは、OAuth や SAML などのべアラートークン認証方法を使用します。また、ヘッダー、パス、クエリ文字列、ステージ変数、コンテキスト変数のリクエストパラメータで記述される情報も使用します。

注記

パスパラメータは、メソッドを呼び出す権限を付与または拒否するために使用できますが、ID ソースを定義するために使用することはできません。これは、認可ポリシーのキャッシングキーの一部として使用できます。ID ソースとして設定できるのは、ヘッダー、クエリ文字列、ステージ変数、コンテキスト変数のみです。

クライアントが API メソッドを呼び出すと、API Gateway は API メソッドに Lambda オーソライザーが設定されているかどうかを確認します。設定されている場合、API Gateway は Lambda 関数を呼び出します。この呼び出しでは、API Gateway は、トークンベースのオーソライザー用に指定されたリクエストヘッダーから抽出された認証トークンを指定するか、受信リクエストパラメータでリクエストパラメータベースのオーソライザー関数に入力 (例: event パラメータ) として渡します。

API Gateway Lambda 認証の流れ

JSON Web Token (JWT) 認証や OAuth プロバイダー呼び出しなどのさまざまな認証方法を実装できます。受信リクエストのパラメータ値に基づいてカスタムスキームを実装して、リクエストを承認する IAM ポリシーを返すこともできます。返されたポリシーが無効であるかアクセス権限が拒否された場合、API 呼び出しは成功しません。ポリシーが有効な場合、API Gateway は、受信トークンと関連付けて、返されたポリシーをキャッシュするか、ID ソースのリクエストパラメータをキャッシュします。その後、キャッシュされたポリシーは最大 3600 秒の事前設定された有効期限 (TTL) までキャッシュに格納され、現在および以降のリクエストに使用されます。TTL 期限を 0 秒に設定すると、ポリシーのキャッシュを無効にすることができます。デフォルトの TTL 値は 300 秒です。現在、TTL の最大値は 3600 秒を超えることはできません。

API Gateway Lambda オーソライザーのタイプ

API Gateway では、TOKEN タイプおよび REQUEST タイプの Lambda オーソライザーがサポートされています。

  • TOKEN タイプの Lambda オーソライザーは、ヘッダーで渡された認証トークンを使用して、指定されたリクエストを呼び出すためのアクセス権限を発信者に付与します。トークンは、OAuth トークンなどを使用します。

  • REQUEST タイプの Lambda オーソライザーは、リクエストパラメータ (例: ヘッダー、クエリ文字列、ステージ変数、コンテキストパラメータ) を使用して、指定されたリクエストを呼び出すためのアクセス権限を発信者に付与します。

API Gateway Lambda オーソライザーの Lambda 関数を作成する

API Gateway Lambda オーソライザーを作成する前に、まず、ロジックを実装する AWS Lambda 関数を作成して認証する必要があります。また、必要に応じて発信者を認証します。この関数は、API Gateway Lambda オーソライザーの設計図にあるコードテンプレートを使用して Lambda コンソールで作成できます。または、この awslabs の例に従って、ゼロから作成することもできます。ここでは、例として、設計図を使わずに、シンプルな Lambda 関数を一から作成する方法を説明します。実稼働コードでは、API Gateway Lambda オーソライザーの設計図に従って認証用の Lambda 関数を実装してください。

API Gateway Lambda オーソライザーの Lambda 関数を作成する際に、この関数から他の AWS サービスを呼び出す場合は、Lambda 関数に実行ロールを割り当てるよう求められます。次の例では、基本的な AWSLambdaRole で十分です。より複雑なユースケースの場合は、Lambda 関数の実行ロールでアクセス権限を付与するための指示に従ってください。

Lambda オーソライザーの Lambda 関数を制御する

Lambda オーソライザーで使用する Lambda 関数を制御するために、authorizer:create または create-authorizer を呼び出すアクセス権限を別の AWS アカウントに付与するには、次の IAM ポリシーを作成します。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "apigateway:POST" ], "Resource": [ "arn:aws:apigateway:region::/restapis/restapi_id/authorizers" ], //Create Authorizer operation is allowed only with the following Lambda function "Condition": { "StringEquals": { "apigateway:AuthorizerUri": "arn:aws:lambda:region:account-id:function:lambda-function-name" } } } ] }

TOKEN タイプの Lambda オーソライザー用に Lambda 関数を作成する

TOKEN タイプの API Gateway Lambda オーソライザーの例として、Lambda コンソールのコードエディタで、以下の Node.js コードを入力します。

// A simple TOKEN 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', the function // returns the 'Unauthorized' error with an HTTP status code of 401. For any other token value, // the authorizer returns an 'Invalid token' error. exports.handler = function(event, context, callback) { var token = event.authorizationToken; switch (token.toLowerCase()) { 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"); } }; // 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; }

TOKEN タイプの Lambda オーソライザーの場合、API Gateway は、event.authorizationToken として、ソーストークンを Lambda 関数に渡します。このトークンの値に基づき、トークンの値が 'allow' の場合に、前述のオーソライザー関数は、指定されたメソッドで IAM の Allow ポリシーを返します。これにより、発信者は、指定されたメソッドを呼び出すことができます。発信者は 200 OK レスポンスを受け取ります。認証トークンが 'deny' 値の場合、オーソライザー関数は、指定のメソッドで Deny を返します。これにより、発信者はメソッドの呼び出しができなくなります。クライアントは 403 Forbidden レスポンスを受け取ります。トークンが 'unauthorized' の場合、クライアントは 401 Unauthorized レスポンスを受け取ります。トークンが 'fail' またはその他である場合、クライアントは 500 Internal Server Error レスポンスを受け取ります。最後のケースの場合はいずれも、IAM ポリシーは生成されません。また、呼び出しは失敗します。

注記

実稼働コードでは、権限を付与する前にユーザーの認証が必要になる場合があります。その場合は、Lambda 関数で認証ロジックを追加することもできます。このような認証プロバイダーを呼び出す方法については、各プロバイダーが提供するドキュメントを参照してください。

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

オーソライザーからバックエンドに、キャッシュされた認証情報を返すには、context マップを使用します。この際、統合リクエストのマッピングテンプレートを使用します。これにより、バックエンドのユーザーエクスペリエンスを強化するには、キャッシュされた認証情報を使用して、シークレットキーにアクセスする必要性を抑え、リクエストごとに認証トークンを開きます。

Lambda プロキシ統合の場合、API Gateway は、Lambda オーソライザーの context オブジェクトを、入力 event の一部としてバックエンドの Lambda 関数に直接渡します。context のキー/値ペアは、Lambda 関数で $event.requestContext.authorizer.key を呼び出して取得できます。前述の Lambda オーソライザーの例では、keystringKeynumberKeybooleanKey のいずれかです。その値は、それぞれ文字列化されて "stringval""123""true" になります。

先に進む前に、Lambda コンソール内から Lambda 関数をテストすることもできます。テストするには、「Amazon API Gateway Lambda オーソライザーへの入力」の説明に従って、サンプルイベントを設定して入力を指定し、「Amazon API Gateway Lambda オーソライザーからの出力」と互換性のあるその出力を調べることで結果を検証します。次のサブセクションでは、Request オーソライザーの Lambda 関数を作成する方法について説明します。

REQUEST タイプの Lambda オーソライザーの Lambda 関数を作成する

REQUEST タイプの API Gateway Lambda オーソライザーの例として、Lambda コンソールのコードエディタで、以下の簡素化された Lambda 関数の Node.js コードを入力します。

exports.handler = function(event, context, callback) { console.log('Received event:', JSON.stringify(event, null, 2)); // A simple REQUEST 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, // stage variable of StageVar1 and the accountId in the request context all match // specified values of 'headerValue1', 'queryValue1', 'stageValue1', and // '123456789012', 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; var requestContext = event.requestContext; // 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" && requestContext.accountId === "123456789012") { 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); }

必要なパラメータ (HeaderAuth1QueryString1StageVar1accountId) 値が事前定義された値と一致した場合、REQUEST オーソライザーの Lambda 関数は、入力リクエストパラメータを検証して、IAM の Allow ポリシーを指定されたメソッドで返します。これにより、発信者は、指定されたメソッドを呼び出すことができます。発信者は 200 OK レスポンスを受け取ります。それ以外の場合、オーソライザー関数は、Unauthorized エラーを返します。IAM ポリシーは生成されません。

上記の Node.js のサンプルオーソライザー関数は、Lambda プロキシ統合の Lambda 関数入力と同様の入力の解析を含め、REQUEST タイプの Lambda オーソライザーを作成するプログラミングフローを示しています。Java や Python など、Lambda がサポートする他の言語に実装を拡張することができます。たとえば、Java で入力を Lambda リクエストオーソライザーに解析するには、「Lambda プロキシ統合用の API の Java 関数」を参照してください。

先に進む前に、Lambda コンソール内から Lambda 関数をテストすることもできます。テストするには、サンプルイベントを設定して入力を提供し、その出力を調べることで結果を検証します。以下の 2 つのセクションでは、Amazon API Gateway Lambda オーソライザーへの入力Amazon API Gateway Lambda オーソライザーからの出力 について説明します。