AWS SAMで作成したLambda関数にBasic認証をかける方法についてのメモです。
マネジメントコンソールでの操作についての記事はいくつかありましたが、 SAM CLIのみで設定する方法が見つからなかったので試してみました。
環境
$ docker --version
Docker version 20.10.5, build 55c4c88
$ aws --version
aws-cli/2.1.34 Python/3.8.8 Linux/5.4.0-52-generic exe/x86_64.ubuntu.20 prompt/off
$ sam --version
SAM CLI, version 1.21.1
Lambda関数はzip形式で作成しました。
構成
SAMのHelloWorldのテンプレートで作成したディレクトリをベースに 下記の構成にしました。
$ tree .
.
├── README.md
├── basic_auth_function
│ ├── app.py
│ └── requirements.txt
├── hello_world_function
│ ├── app.py
│ └── requirements.txt
├── samconfig.toml
└── template.yaml
Basic認証処理を行うLambda関数
Basic認証を行うLambda関数です。
ユーザー名、パスワードはテキトーです。
basic_auth_function/app.py
:
import json
import base64
def lambda_handler(event, context):
user_id = 'adminxx'
password = 'passwordxx'
auth_str = 'Basic ' + base64.b64encode(f"{user_id}:{password}".encode("utf-8")).decode("ascii")
auth_header = event['headers']['Authorization']
if auth_str != auth_header:
raise Exception('Unauthorized')
return {
'principalId': user_id,
'policyDocument': {
'Version': '2012-10-17',
'Statement': [
{
'Action': 'execute-api:Invoke',
'Effect': 'Allow',
'Resource': event['methodArn']
}
]
}
}
認証処理をかけるAPI
hello world
を返すだけです。
hello_world_function/app.py
:
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
}),
}
SAMのTemplateファイル
template.yaml
:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
hello-world-auth
Sample SAM Template for hello-world-auth
Globals:
Function:
Timeout: 3
Resources:
HelloWorldApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
GatewayResponses:
UNAUTHORIZED:
ResponseParameters:
Headers:
WWW-Authenticate: "'Basic'"
Auth:
AddDefaultAuthorizerToCorsPreflight: false
DefaultAuthorizer: LambdaRequestAuthorizer
Authorizers:
LambdaRequestAuthorizer:
FunctionPayloadType: REQUEST
FunctionArn: !GetAtt BasicAuthFunction.Arn
Identity:
Headers:
- Authorization
ReauthorizeEvery: 300
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world_function/
Handler: app.lambda_handler
Runtime: python3.8
Events:
GetRoot:
Type: Api
Properties:
RestApiId: !Ref HelloWorldApi
Path: /hello
Method: get
BasicAuthFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: basic_auth_function/
Handler: app.lambda_handler
Runtime: python3.8
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${HelloWorldApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
HelloWorldApi
:HelloWorldFunction
を実行するためのエンドポイント。
API GatewayのオーソライザーとしてBasicAuthFunction
を設定し、Basic認証します。HelloWorldFunction
:hello world
を返すAPI、Basic認証された場合に実行されます。BasicAuthFunction
: Basic認証処理。
実行結果
認証なしでアクセスした場合
$ curl -i https://XXXX.execute-api.ap-northeast-1.amazonaws.com/Prod/hello
HTTP/2 401
content-type: application/json
:
www-authenticate: Basic
:
{"message":"Unauthorized"}
Basic認証のオプション(-u ユーザー名:パスワード
)をつけてアクセスした場合
$ curl -i -u adminxx:passwordxx https://XXXX.execute-api.ap-northeast-1.amazonaws.com/Prod/hello
HTTP/2 200
content-type: application/json
:
{"message": "hello world"}
Basic認証情報をつけた場合のみアクセスできるようになりました。
ブラウザでアクセスした場合は、ユーザー名、パスワードの入力を求めるポップアップが表示されます。
ハマったこと
template.yaml
を変更した後に、sam build
を実行せずに、sam deploy
を実行していたため、変更反映されてないことがありました。。
sam deploy
はsam build
で作成した.aws-sam
ディレクトリ配下のファイルを見ているため、template.yaml
を編集したあとは、sam build
が必要でした。
参考URL
AWS Serverless Application Model Developer Guide
Lambda authorizer examples
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-controlling-access-to-apis-lambda-authorizer.html
API GatewayにLambda(Node.js)でBasic認証かける
https://dev.classmethod.jp/articles/apigateway-lambda-basicauth/#toc-6
Amazon API GatewayにBasic認証をかける方法
https://qiita.com/diaphragm/items/b87d700ef36fa62c1aa8
API Gateway + Lambda Authorizer + Lambdaプロキシ統合 + AWS SAM CLIを組み合わせたときのCORS設定
https://qiita.com/kter/items/c2732247db919a5fd51f