使用 Swift 构建的自定义 AWS Lambda 授权器的框架示例

Swift Lambda Authorizer

斯威夫特 5.7

该项目是 Swift in the Cloud 系列的一部分,旨在演示构建基于 Swift 的 Lambda API 的基础知识,该 API 可以从多个区域请求。要成功完成以下步骤,您应该从本系列的开头开始学习 AWS Swift 多区域 API 项目。

要求

要完成此设置,您需要:

  1. Xcode 14+
  2. 码头工人 4+
  3. AWS CLI(用于访问 AWS Swift 多区域 API 项目中使用的 AWS 账户的设置)

开始

默认情况下,此代码将为 Graviton Lambda 实例构建一个 Swift ARM 包。

安装

  1. 在 AWS S3 中为您开始安装 Cloudformation 堆栈的同一区域中的项目创建一个存储桶。 将由云形成模板翻译为 .例如:如果在模板存储桶名称中设置,则将是 Cloudformation 模板在 us-east-2(俄亥俄州)中查找的存储桶名称。bucketnameswiftlambda-regionnameswiftlambdaswiftlambda-us-east-2
  2. 本地克隆SwiftLambdaAuthorizer
  3. 确保 docker 正在运行
  4. 从命令行将目录更改为项目。
  5. 跑。要更改可用选项,请运行./build.sh./build.sh -h
  6. 跑。要更改可用选项,请运行./package.sh./package.sh -h

cd SwiftLambdaAuthorizer/

# Build SwiftLambdaAuthorizer
# Available Swift AmazonLinux2 versions: https://hub.docker.com/_/swift/?tab=tags
./build.sh -v 5.7.2 -a linux/arm64

# Package SwiftLambdaAuthorizer for upload to S3
./package.sh -n SwiftLambdaAuthorizer

# Upload to S3 via AWS CLI. Change bucketName and the keyPath as needed
# NB: You can also just upload the file lambda.zip via the AWS S3 Console
aws s3 cp .build/lambda/SwiftLambdaAuthorizer/lambda.zip s3://swiftlambda-us-east-2/SwiftLambdaAuthorizer/

Make a note of the final keyPath of the upload. You will need this for the AWS Swift Multi-Region API CloudFormation template.

Package Dependencies

This project makes use of:

Testing Locally

You can also build and run this code locally in Xcode. To do this you will need to set an environment variable to enable the lambda server to run locally. Use Xcode’s scheme editor to add environment variables to your app. In the Xcode menu, go to Product > Scheme > Edit Scheme. Select Run on the left, select Arguments in the main window. Under Environment Variables add Name: , Value: .LOCAL_LAMBDA_SERVER_ENABLEDtrue

Build and run the project and you should see Output similar to the following:

2023-01-10T16:01:11-0500 info LocalLambdaServer : [AWSLambdaRuntimeCore] LocalLambdaServer started and listening on 127.0.0.1:7000, receiving events on /invoke
2023-01-10T16:01:11-0500 info Lambda : [AWSLambdaRuntimeCore] lambda lifecycle startingwith Configuration
	General(logLevel: info))
	Lifecycle(id: 24655414529708, maxTimes: 0, stopSignal: TERM)
RuntimeEngine(ip: 127.0.0.1, port: 7000, requestTimeout: nil

This allows you to POST requests to 127.0.0.1 (localhost) on port 7000 and have the authorizer response. The format of these requests, is expected to be in the same format (version 2.0) that APIGateway uses to talk to Lambda Authorizers.

For testing you can copy the example below and use it locally. The only change made to the AWS v2.0 default is to add the header. In this example, the header must be set to the value hardcoded in the code as the variable to get a response allowing access. This simplified authentication is setup for testing purposes only. In production code you would be expected to use more robust authentication methods eg: JWT. From the command line you can run this via curl.authorizationSwiftLambdaAuthorizerhardCodedExpectedAuthorizationHeaderValue

## SwiftLambdaAuthorizer (POST) local 
curl -X "POST" "http://localhost:7000/invoke" \
     -H 'Content-Type: application/json' \
     -d $'{
  "identitySource": [
    "user1",
    "123"
  ],
  "version": "2.0",
  "headers": {
    "Header2": "value2",
    "authorization": "SKOcSFZd8pKoZ24WXYK2dSEc5Nf2eao9QOOvpPYM"
  },
  "rawPath": "/my/path",
  "type": "REQUEST",
  "stageVariables": {
    "stageVariable2": "value2",
    "stageVariable1": "value1"
  },
  "routeKey": "$default",
  "cookies": [
    "cookie1",
    "cookie2"
  ],
  "requestContext": {
    "accountId": "123456789012",
    "time": "12/Mar/2020:19:03:58 +0000",
    "http": {
      "path": "/my/path",
      "userAgent": "agent",
      "method": "POST",
      "protocol": "HTTP/1.1",
      "sourceIp": "IP"
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "timeEpoch": 1583348638390,
    "authentication": {
      "clientCert": {
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "clientCertPem": "CERT_CONTENT",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        },
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer"
      }
    },
    "domainPrefix": "id",
    "apiId": "api-id",
    "routeKey": "$default",
    "requestId": "id",
    "stage": "$default"
  },
  "pathParameters": {
    "parameter1": "value1"
  },
  "queryStringParameters": {
    "parameter2": "value",
    "parameter1": "value1,value2"
  },
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "routeArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request"
}'

Next Steps

As mentioned above this project is part of the Swift in the Cloud Series. The next step is to go back the AWS Swift Multi-Region API and complete the SwiftLambdaAuthorizer lambda template stack with the parameter data generated here.

Further Improvements

Time will bring changes to this project. To really make this setup robust, it can be improved by adding:

  1. Testing is ignored in this project. As it develops testing may become more relevant.
  2. Simpler build and packaging scripting
  3. Better automation via the AWS CLI

License

SwiftLambdaAuthorizer is released under the Apache License, Version 2.0. See LICENSE for details.

GitHub

点击跳转