Skip to content

Commit 8ff581c

Browse files
committed
Add Lambda Authorizer to the example
1 parent db5257c commit 8ff581c

File tree

8 files changed

+127
-18
lines changed

8 files changed

+127
-18
lines changed

Examples/quoteapi/Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
### Add functions here and link them to builder-bot format MUST BE "build-FunctionResourceName in template.yaml"
22

33
build-QuoteService: builder-bot
4+
build-LambdaAuthorizer: builder-bot
45

56
# Helper commands
67
build:
@@ -16,10 +17,14 @@ tail:
1617
sam logs --stack-name QuoteService --name QuoteService --tail
1718

1819
local:
19-
LOCAL_LAMBDA_SERVER_ENABLED=true swift run QuoteService
20+
swift run QuoteService
21+
22+
local-invoke:
23+
curl -v -H 'Authorization: 123' -X POST --data @events/GetQuote.json http://127.0.0.1:7000/invoke
2024

2125
invoke:
22-
curl -v -H 'Authorization: 123' https://k3lbszo7x6.execute-api.us-east-1.amazonaws.com/stocks/AAPL
26+
## curl -v -H 'Authorization: 123' https://<REPLACE_WITH_YOUR_API_URI>/stocks/AAPL
27+
curl -v -H 'Authorization: 123' https://xb6a6h6x33.execute-api.us-east-1.amazonaws.com/stocks/AAPL
2328

2429
###################### No Change required below this line ##########################
2530

Examples/quoteapi/Package.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ let package = Package(
1616
.package(url: "https://github.com/apple/swift-openapi-runtime.git", from: "1.8.2"),
1717
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "2.0.0-beta.1"),
1818
.package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", from: "1.2.0"),
19-
// .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.4.0"),
2019
// .package(url: "https://github.com/swift-server/swift-openapi-lambda.git", from: "0.3.0"),
2120
.package(name: "swift-openapi-lambda", path: "../.."),
2221
],
@@ -29,7 +28,7 @@ let package = Package(
2928
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
3029
.product(name: "OpenAPILambda", package: "swift-openapi-lambda"),
3130
],
32-
path: "Sources",
31+
path: "Sources/QuoteAPI",
3332
resources: [
3433
.copy("openapi.yaml"),
3534
.copy("openapi-generator-config.yaml"),
@@ -40,6 +39,14 @@ let package = Package(
4039
package: "swift-openapi-generator"
4140
)
4241
]
43-
)
42+
),
43+
.executableTarget(
44+
name: "LambdaAuthorizer",
45+
dependencies: [
46+
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
47+
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"),
48+
],
49+
path: "Sources/LambdaAuthorizer",
50+
),
4451
]
4552
)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftAWSLambdaRuntime open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the SwiftAWSLambdaRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import AWSLambdaEvents
16+
import AWSLambdaRuntime
17+
18+
//
19+
// This is an example of a policy authorizer that always authorizes the request.
20+
// The policy authorizer returns an IAM policy document that defines what the Lambda function caller can do and optional context key-value pairs
21+
//
22+
// This code is shown for the example only and is not used in this demo.
23+
// This code doesn't perform any type of token validation. It should be used as a reference only.
24+
let policyAuthorizerHandler:
25+
(APIGatewayLambdaAuthorizerRequest, LambdaContext) async throws -> APIGatewayLambdaAuthorizerPolicyResponse = {
26+
(request: APIGatewayLambdaAuthorizerRequest, context: LambdaContext) in
27+
28+
context.logger.debug("+++ Policy Authorizer called +++")
29+
30+
// typically, this function will check the validity of the incoming token received in the request
31+
32+
// then it creates and returns a response
33+
return APIGatewayLambdaAuthorizerPolicyResponse(
34+
principalId: "John Appleseed",
35+
36+
// this policy allows the caller to invoke any API Gateway endpoint
37+
policyDocument: .init(statement: [
38+
.init(
39+
action: "execute-api:Invoke",
40+
effect: .allow,
41+
resource: "*"
42+
)
43+
44+
]),
45+
46+
// this is additional context we want to return to the caller
47+
context: [
48+
"abc1": "xyz1",
49+
"abc2": "xyz2",
50+
]
51+
)
52+
}
53+
54+
//
55+
// This is an example of a simple authorizer that always authorizes the request.
56+
// A simple authorizer returns a yes/no decision and optional context key-value pairs
57+
//
58+
// This code doesn't perform any type of token validation. It should be used as a reference only.
59+
// let simpleAuthorizerHandler:
60+
// (APIGatewayLambdaAuthorizerRequest, LambdaContext) async throws -> APIGatewayLambdaAuthorizerSimpleResponse = {
61+
// (_: APIGatewayLambdaAuthorizerRequest, context: LambdaContext) in
62+
63+
// context.logger.debug("+++ Simple Authorizer called +++")
64+
65+
// // typically, this function will check the validity of the incoming token received in the request
66+
67+
// return APIGatewayLambdaAuthorizerSimpleResponse(
68+
// // this is the authorization decision: yes or no
69+
// isAuthorized: true,
70+
71+
// // this is additional context we want to return to the caller
72+
// context: ["abc1": "xyz1"]
73+
// )
74+
// }
75+
76+
// create the runtime and start polling for new events.
77+
// in this demo we use the simple authorizer handler
78+
let runtime = LambdaRuntime(body: policyAuthorizerHandler)
79+
try await runtime.run()

Examples/quoteapi/Sources/QuoteService.swift renamed to Examples/quoteapi/Sources/QuoteAPI/QuoteService.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@ struct QuoteServiceImpl: APIProtocol, OpenAPILambdaHttpApi {
2727
}
2828

2929
static func main() async throws {
30-
let logger = Logger(label: "OpenAPILambda")
3130
let lambda = try OpenAPILambdaHandler<QuoteServiceImpl>()
3231

3332
// Instantiate LambdaRuntime with a handler implementing the business logic of the Lambda function
34-
let lambdaRuntime = LambdaRuntime(logger: logger, body: lambda.handler)
33+
let lambdaRuntime = LambdaRuntime(body: lambda.handler)
3534
try await lambdaRuntime.run()
3635
}
3736

File renamed without changes.
File renamed without changes.

Examples/quoteapi/template.yml

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ Globals:
88
CodeUri: .
99
Handler: swift.bootstrap
1010
Runtime: provided.al2
11-
MemorySize: 512
11+
MemorySize: 256
1212
Architectures:
1313
- arm64
1414

1515
Resources:
16-
# Lambda function
16+
# QuoteService Lambda function
1717
QuoteService:
1818
Type: AWS::Serverless::Function
1919
Properties:
@@ -32,30 +32,50 @@ Resources:
3232
ApiId: !Ref MyProtectedApi
3333
Path: /{proxy+}
3434
Method: ANY
35-
Auth:
36-
Authorizer: MyLambdaAuthorizer
3735

3836
Metadata:
3937
BuildMethod: makefile
4038

39+
# Lambda authorizer function
40+
LambdaAuthorizer:
41+
Type: AWS::Serverless::Function
42+
Properties:
43+
Timeout: 29 # max 29 seconds for Lambda authorizers
44+
Environment:
45+
Variables:
46+
# by default, AWS Lambda runtime produces no log
47+
# use `LOG_LEVEL: debug` for for lifecycle and event handling information
48+
# use `LOG_LEVEL: trace` for detailed input event information
49+
LOG_LEVEL: debug
50+
Metadata:
51+
BuildMethod: makefile
52+
53+
# The API Gateway
4154
MyProtectedApi:
4255
Type: AWS::Serverless::HttpApi
4356
Properties:
4457
Auth:
4558
DefaultAuthorizer: MyLambdaAuthorizer
4659
Authorizers:
4760
MyLambdaAuthorizer:
48-
AuthorizerPayloadFormatVersion: 2.0
49-
EnableFunctionDefaultPermissions: true
50-
EnableSimpleResponses: true
51-
FunctionArn: arn:aws:lambda:us-east-1:486652066693:function:LambdaAuthorizer-LambdaAuthorizer-TSH4AsHiqICi
61+
FunctionArn: !GetAtt LambdaAuthorizer.Arn
5262
Identity:
5363
Headers:
54-
- Authorization
64+
- Authorization
65+
AuthorizerPayloadFormatVersion: "2.0"
66+
EnableSimpleResponses: true
67+
68+
# Give the API Gateway permissions to invoke the Lambda authorizer
69+
AuthorizerPermission:
70+
Type: AWS::Lambda::Permission
71+
Properties:
72+
Action: lambda:InvokeFunction
73+
FunctionName: !Ref LambdaAuthorizer
74+
Principal: apigateway.amazonaws.com
75+
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${MyProtectedApi}/*
5576

5677
# print API endpoint
5778
Outputs:
5879
SwiftAPIEndpoint:
5980
Description: "API Gateway endpoint URL for your application"
6081
Value: !Sub "https://${MyProtectedApi}.execute-api.${AWS::Region}.amazonaws.com"
61-
# Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com"

Package.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ let package = Package(
1111
.package(url: "https://github.com/apple/swift-openapi-runtime.git", from: "1.8.2"),
1212
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "2.0.0-beta.1"),
1313
.package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", from: "1.2.0"),
14-
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.4.0"),
1514
],
1615
targets: [
1716
.target(

0 commit comments

Comments
 (0)