10
5

More than 1 year has passed since last update.

Lambdaの関数 URL(Function URLs) を使用時、Basic認証をかける

Last updated at Posted at 2022-07-03

はじめに

先日、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を使用する方法(下記記事)があります。

スクリーンショット 2022-07-03 18.35.50.png

ただし、AWS_IAMが使用できず、NONEにした場合でも特定のリソースのみLambdaを使用できるようにBasic認証をかけていきます。

Lambda作成

  • 作成時、関数URLを有効にする。
    スクリーンショット 2022-07-03 18.37.45.png
  • ユーザー名とパスワードは環境変数にします。
    • PASSWORD
      • password
    • USERNAME
      • admin

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と表示されます。

参照

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5