I have created some Lambda Functions and deployed them using SAM. The deployment is successful, but when trying to reach the endpoints I always obtain
{ message: "Unauthorized" }
Even I'm sending a correct Bearer token using the Authentication
header.
Then if I go to the Authorizer and run the test, it passes well and generates logs in CloudWatch, but when I run a request from my frontend app or a REST client app to the endpoint, I get the unauthorized message and checking CloudWatch, there's not an execution of the authorizer function.
Besides, checking the Authorizer function from the Lambda configuration, I can see that there's an error in the API Gateway Trigger
, but don't know what it means.
I created the authorizer function using the guide provided by AWS: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html#api-gateway-lambda-authorizer-lambda-function-create
Sharing my SAM configuration
Resources:
SomeAPI:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
TracingEnabled: true
Auth:
DefaultAuthorizer: MyLambdaTokenAuthorizer
Authorizers:
MyLambdaTokenAuthorizer:
FunctionArn: !GetAtt AuthorizerFunction.Arn
GetActivityStreamFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: get-activity-stream/
Handler: index.handler
Layers:
- !Ref DepencenciesLayer
- !Ref DatabaseLayer
Events:
GetActivityStream:
Type: Api
Properties:
RestApiId: !Ref SomeAPI
Path: /activity-stream
Method: get
## Authorizer Function
AuthorizerFunction:
Type: AWS::Serverless::Function
Properties:
Layers:
- !Ref DepencenciesLayer
CodeUri: authorizer/
Handler: index.handler
Regarding the response sent back by the Authorizer, it sends all the params requested by API Gateway
{
principalId: decoded.sub,
policyDocument: getPolicyDocument("Allow", params.methodArn),
context: { scope: decoded.scope }
}
The runtime I'm using is nodejs12.x
, and here are some screenshots of what a I get from AWS console.
After lots of hours testing different things found by Internet, I started to have improvements when I noticed that the policy document was wrong:
Before
const policyDocument = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": effect,
"Action": "execute-api:Invoke",
"Resource": resource
}
]
};
After
const policyDocument = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": effect,
"Action": [
"execute-api:Invoke"
],
"Resource": [
resource
]
}
]
};
Where Action
and Resource
should be arrays. Also I set the resource
variable to be '*'
instead of event.methodArn
, because when caching the authorizations the policy cached matches only the first endpoints reached, while next calls to other endpoints result in the error: user not authorized for the method requested
.
Other change was in the template.yaml
Resources:
SomeAPI:
Type: AWS::Serverless::Api
Auth:
DefaultAuthorizer: MyLambdaTokenAuthorizer
AddDefaultAuthorizerToCorsPreflight: false
Authorizers:
MyLambdaTokenAuthorizer:
FunctionArn: !GetAtt AuthorizerFunction.Arn
Identity:
Header: Authorization
ValidationExpression: Bearer.*
AddDefaultAuthorizerToCorsPreflight
with false
value makes the preflight calls (OPTIONS
), to not be verified, because the preflight request are done by the browser, otherwise all the calls from Axios
also fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With