API Gateway での REST API へのアクセスの制御と管理
概要
AWS LambdaにアクセスするAPI Gatewayのエンドポイントを叩く際に、セキュアな認証をかける方法のうちAuthorizerを使用した認証方法をメモしておきたいと思います。
目次
- 構成
- 認証ワークフロー
- オーソライザーの設定
- まとめ
- 参考
構成
認証ワークフロー
Lambda オーソライザーには、2種類存在します。
1.トークンベースの認証方法を検証します。 の Lambda オーソライザー (TOKEN オーソライザーとも呼ばれる) は、JSON ウェブトークン (JWT) や OAuth トークンなどのベアラートークンで発信者 ID を受け取ります。
2.リクエストパラメータベースの Lambda オーソライザー (REQUEST オーソライザーとも呼ばれます) は、ヘッダー、クエリ文字列パラメータ、stageVariables、および $context 変数の組み合わせで発信者 ID を受け取ります。
この記事では、トークンベースの認証方法を検証します。
オーソライザーの作成
1.任意の関数とエンドポイントを作成
まず認証検証用に、テスト関数を作成します。上記構成図で、最後にアクセスを受けるFunctionです。
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('I am called by authorized clients'),
};
return response;
};
関数を作成後、API Gatewayトリガーを設定しAPIを作成し、このエンドポイントへのGETリクエストに認証用のパラメータを含めます。
-
API
api-gateway/{api-id}///demoAPI -
Endpoint
https://{api-id}.execute-api.{region}.amazonaws.com/default/demo
- API名
demoAPI
2.オーソライザー関数の作成
exports.handler = function(event, context, callback) {
//リクエストヘッダーに含まれる認証トークンを取得。
//このトークンはAPIが発行する。
var token = event.authorizationToken;
// ヘッダーリクエストに含まれるauthorizationTokenがAllowなら、IAMポリシーの生成
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;
}
3.APIにオーソライザーを追加
1.で作成したAPIにオーソライザーを追加します。
2.[タイプ] で [Lambda] を選択します。
3.[Lambda 関数] で、Lambda オーソライザー関数を作成したリージョンを選択し、ドロップダウンリストで関数名を選択します。
4.[Lambda 呼び出しロール] は空白のままにします。
5.[Lambda イベントペイロード] の場合は、[トークン] を選択します。
6.[Token Source (トークンのソース)] に「authorizationToken」と入力します。
7.[Create (作成)] を選択し、[Grant & Create (付与 & 作成)] を選択します
4.動作確認
- トークンがallowの場合
$ curl -H "authorizationToken: allow" https://{api-id}.execute-api.{region}.amazonaws.com/demo
// response
"I am called by authorized clients"
{
"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の場合
$ curl -H "authorizationToken: deny" https://{api-id}.execute-api.{region}.amazonaws.com/demo
// response
{"Message":"User is not authorized to access this resource with an explicit deny"}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Deny",
"Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
}
]
}
まとめ
AWSのIAMポリシーは、適切に使用しないとセキュリティ面で危ないです。Lambda関数へのアクセスには、オーソライザーを使用してセキュアな認証を常に設定するようにしたいです。
Discussion