はじめに
先日、Lambda単体でHTTPSエンドポイントから実行可能になる機能が追加しました。
特定のリソースのみLambdaを実行できるようにするためには、Basic認証を適用する必要があったため、その方法についてまとめます。
Lambdaを実行する認証タイプ
-
AWS_IAM
– IAM の権限に基づいて、リクエストを認証および承認します。権限は、lambda:InvokeFunctionUrl
を付与したIAMポリシーをIAMロール、もしくは、IAMユーザーに適用し、lambdaを呼びます。- アクセスするためには
AWS Signature Version 4 (SigV4)
を使用して、HTTPリクエストに対して署名する必要があります。
- アクセスするためには
-
NONE
– Lambda を呼び出す前の認証を実行しません。関数 URL への、未認証でパブリックなアクセスを許可するには、このオプションを選択します。
特定のリソースのみLambdaを実行できるようにするためには、認証タイプのAWS_IAM
を選択し、権限を付与したawsリソースもしくは、AWS SDKを使用する方法(下記記事)があります。
ただし、AWS_IAM
が使用できず、NONE
にした場合でも特定のリソースのみLambdaを使用できるようにBasic認証をかけていきます。
Lambda作成
Lambdaのコード
exports.handler = async (event) => {
console.log('event:', JSON.stringify(event, null, 2));
const authorizationHeader = event.headers.authorization;
if (!authorizationHeader) return ('Unauthorized');
const encodedCreds = authorizationHeader.split(" ")[1];
const plainCreds = (new Buffer.from(encodedCreds, 'base64')).toString().split(':');
const username = plainCreds[0];
const password = plainCreds[1];
if (!(username === process.env.USERNAME && password === process.env.PASSWORD)) return ('Unauthorized');
// Write the code you want to execute
return ( "ok");
};
今回、誰でもURLを呼べはしますが、Basic認証に成功しなければ、以降のコードを実行できません。
event内容はこちらです。
{
"version": "2.0",
"routeKey": "$default",
"rawPath": "/",
"rawQueryString": "",
"headers": {
"authorization": "Basic YWRtaW46cGFzc3dvcmQ=",
"x-amzn-tls-cipher-suite": "ECDHE-RSA-AES128-GCM-SHA256",
"x-amzn-tls-version": "TLSv1.2",
"x-amzn-trace-id": "Root=1-62c16503-6b13cbf473d2d54659fd3bd1",
"x-forwarded-proto": "https",
"host": "3uu2x5movnumaapubfmjdonp5a0cwvde.lambda-url.ap-northeast-1.on.aws",
"x-forwarded-port": "443",
"x-forwarded-for": "111.111.111.111",
"accept": "*/*",
"user-agent": "curl/7.79.1"
},
"requestContext": {
"accountId": "anonymous",
"apiId": "3uu2x5movnumaapubfmjdonp5a0cwvde",
"domainName": "3uu2x5movnumaapubfmjdonp5a0cwvde.lambda-url.ap-northeast-1.on.aws",
"domainPrefix": "3uu2x5movnumaapubfmjdonp5a0cwvde",
"http": {
"method": "GET",
"path": "/",
"protocol": "HTTP/1.1",
"sourceIp": "111.111.111.111",
"userAgent": "curl/7.79.1"
},
"requestId": "6492f838-fabb-4fbe-a474-31f44bf7d85f",
"routeKey": "$default",
"stage": "$default",
"time": "03/Jul/2022:09:44:35 +0000",
"timeEpoch": 1656841475184
},
"isBase64Encoded": false
}
Lambdaを呼んで見る
ローカルから呼んでみます。
$ curl https://admin:password@3uu2x5movnumaapubfmjdonp5a0cwvde.lambda-url.ap-northeast-1.on.aws/
ok
$ curl https://3uu2x5movnumaapubfmjdonp5a0cwvde.lambda-url.ap-northeast-1.on.aws/\
-H "authorization:Basic YWRtaW46cGFzc3dvcmQ="
ok
どちらの呼び方でもBasic認証を成功しています。
YWRtaW46cGFzc3dvcmQ=
は、admin:password
をエンコードしています。
$ curl https://3uu2x5movnumaapubfmjdonp5a0cwvde.lambda-url.ap-northeast-1.on.aws/\
-H "authorization:Basic YWRtaW46cGF"
Unauthorized
失敗した場合、Unauthorized
と表示されます。
参照