Override default auth in SAM templates and Open API - amazon-web-services

I have made a SAM template that deploys a mix of public and authenticated endpoints. The default auth is oauth. For public endpoints, I use overrides to make it auth NONE. This worked fine.
After I have added the OpenAPI for documentation. The auth override for public endpoints does not work anymore. What else should I do?
#sam-template.yaml
Resources:
RestApi:
Type: AWS::Serverless::Api
Properties:
Name: !Ref ApiStackName
StageName: Prod
Auth:
AddDefaultAuthorizerToCorsPreflight: false
DefaultAuthorizer: TokenAuthorizer
Authorizers:
TokenAuthorizer:
FunctionArn: !GetAtt Authorizer.Arn
Identity:
Header: Authorization
ValidationExpression: Bearer.*
ReauthorizeEvery: 0
DefinitionBody: // this is what I added.
Fn::Transform:
Name: AWS::Include
Parameters:
Location:
Fn::Join:
- ''
- - 's3://'
- Ref: S3BucketName
- '/swagger.yaml'
GetFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./functions
FunctionName: !Sub ${Environment}-api-get
Description: get
Handler: ./src/get.handler
Role: !Sub arn:aws:iam::${AWS::AccountId}:role/pam-${Environment}-${AWS::Region}-get-lambda-role
Events:
Api:
Type: Api
Properties:
RestApiId: !Ref RestApi
Path: /p
Method: GET
Auth:
Authorizer: NONE // this overrides the default auth
#swagger.yaml
/p:
get:
summary: Get
description: Get
responses:
200:
description: "200 response"
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/P"
500:
description: "500 response"
content: {}
x-amazon-apigateway-auth:
type: "NONE"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetFunction.Arn}/invocations
responses:
default:
statusCode: "200"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"

security: {}
OR
security:
- {}
Didn't work for me.
The below mentioned code snippet worked.
security:
- NONE: []

you are looking for security in OpenAPI. This sets Authorization on ApiGateway endpoint to NONE.
/p:
get:
summary: Get
description: Get
responses:
...
security:
- {}
x-amazon-apigateway-integration:
...

Related

Getting access denied due to origin blocked by CORS in AWS Api-Gateway

I have an AWS SAM template, which creates lambda function and post method in API Gateway. By default, it uses Lambda Proxy integration and it is working fine when I am testing through the PostMan tool but when I am using the API gateway URL with my sandbox app, it is displaying the following error.
Access to XMLHttpRequest at 'https://abcdef.execute-api.eu-west-2.amazonaws.com/dev/my-api' from origin 'https://abcd.csb.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
but when I am creating API gateway post method manually and trying then it is working fine.
Lambda function also returning following header in the response.
response = {
'statusCode': status_code,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST'
},
'body': json.dumps(response_data)
}
Following is AWS SAM template.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
AWS SAM Template
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 10
Parameters:
DeploymentEnv:
Type: String
Resources:
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
EndpointConfiguration:
Type: REGIONAL
Cors:
AllowMethods: "'POST,OPTIONS'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
AllowOrigin: "'*'"
MaxAge: "'600'"
AllowCredentials: false
Auth:
DefaultAuthorizer: NONE
ApiKeyRequired: true # sets for all methods
LambdaFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
FunctionName: !Join [ "", [ !Ref DeploymentEnv, "-my-lambda"]]
CodeUri: my_api/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
EventTriggerlambda:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /my-api
Method: POST
Auth:
ApiKeyRequired: true
Role: Role_URN
Environment:
Variables:
URI: Test
USER_NAME: Test
PASSWORD: Test
ApiKey:
Type: AWS::ApiGateway::ApiKey
DependsOn: ApiGatewayApiStage
Properties:
Name: !Join ["", [{"Ref": "AWS::StackName"}, "-apikey"]]
Enabled: true
StageKeys:
- RestApiId: !Ref ApiGatewayApi
StageName: !Ref DeploymentEnv
UsagePlan:
DependsOn:
- ApiGatewayApiStage
Type: AWS::ApiGateway::UsagePlan
Properties:
ApiStages:
- ApiId: !Ref ApiGatewayApi
Stage: !Ref DeploymentEnv
Throttle:
BurstLimit: 500
RateLimit: 100
UsagePlanName: MY-UsagePlan
UsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
Properties:
KeyId: !Ref ApiKey
KeyType: API_KEY
UsagePlanId: !Ref UsagePlan
Outputs:
LambdaFunction:
Description: "Lambda Function ARN"
Value: !GetAtt LambdaFunction.Arn
Please help, Thanks :)
Configuration is not proper for API creation in API-Gateway in the AWS SAM template. because SAM deployment uses lambda proxy integration by default that's why in method response, there are few values required which can not be set automatically using the above configuration. So I use open API specification where I defined Rest API configuration and it is working fine without any manual intervention after deployment.
Following configuration is fine.
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location: !Join [ '', [ 's3://mybucket', '/openapi-spec.yaml' ] ]
EndpointConfiguration:
Type: REGIONAL
OpenAPi Configuration
openapi: "3.0.1"
info:
title: "test-api"
description: "Created by AWS Lambda"
version: "2022-01-07T18:00:40Z"
paths:
/test-api:
post:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
httpMethod: "POST"
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: "when_no_match"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
options:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
Access-Control-Allow-Methods:
schema:
type: "string"
Access-Control-Allow-Headers:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
requestTemplates:
application/json: "{\"statusCode\": 200}"
passthroughBehavior: "when_no_match"
type: "mock"
x-amazon-apigateway-any-method:
responses:
"200":
description: "200 response"
content: {}
security:
- api_key: []
x-amazon-apigateway-integration:
httpMethod: "POST"
uri: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunction.Arn}/invocations"
responses:
".*":
statusCode: "200"
passthroughBehavior: "when_no_match"
type: "aws_proxy"
components:
schemas:
Empty:
title: "Empty Schema"
type: "object"
securitySchemes:
api_key:
type: "apiKey"
name: "x-api-key"
in: "header"
here openapi-spec.yaml file was kept in the same folder as the AWS SAM template and it was uploaded to the S3 bucket before deployment start using the following command in the GitHub workflow pipeline file.
- run: aws s3 cp openapi-spec.yaml s3://mnai-code-deployments
- run: sam build
- run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset --stack-name my-stack --s3-bucket mybucket --capabilities CAPABILITY_IAM --region eu-west-2 --parameter-overrides ParameterKey=DeploymentEnv,ParameterValue=dev ParameterKey=S3Bucket,ParameterValue=mybucket
Thanks

How to import variable into Swagger file for AWS ApiGateway

I Want to use APIGateway for my RESTful application by OpenApi file but How could I inject my variables from outside of swagger file into it
Swagger.yml
openapi: "3.0.1"
info:
title: !Join ['-', ['XXXX', !Ref ServiceName]]
paths:
/:
get:
responses:
default:
description: "Default response for GET /"
x-amazon-apigateway-integration:
payloadFormatVersion: "1.0"
connectionId: !Ref VPCLink
type: "http_proxy"
httpMethod: "ANY"
uri: !GetAtt ServiceDiscovery.Arn
connectionType: "VPC_LINK"
/health:
get:
responses:
default:
description: "Default response for GET /health"
x-amazon-apigateway-integration:
payloadFormatVersion: "1.0"
connectionId: !Ref VPCLink
type: "http_proxy"
httpMethod: "ANY"
uri: !GetAtt ServiceDiscovery.Arn
connectionType: "VPC_LINK"
x-amazon-apigateway-cors:
allowOrigins:
- '*'
allowHeaders:
- '*'
allowMethods:
- 'GET'
x-amazon-apigateway-importexport-version: "1.0"
Cloudformation template :
HttpApi:
Type: AWS::ApiGatewayV2::Api
Properties:
Body:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: "s3://XXXX/Swagger.yml"
But It has following error in cloudformation :
"Transform AWS::Include failed with: The specified S3 object's content should be valid Yaml/JSON"
And when I remove built-in functions like Join and GetAtt from my swagger.yml it works.

How to add non authenticated routes in AWS SAM template

So this is my SAM template:
webApi:
Type: AWS::Serverless::Api
Properties:
Auth:
DefaultAuthorizer: CognitoAuthorizer
Authorizers:
CognitoAuthorizer:
UserPoolArn: !GetAtt myUserPool.Arn
AddDefaultAuthorizerToCorsPreflight: false
Cors:
AllowMethods: "'*'"
AllowHeaders: "'*'"
AllowOrigin: "'*'"
StageName: !Ref Environment
DefinitionBody:
swagger: "2.0"
info:
title:
Ref: AWS::StackName
paths:
/path/one:
post:
responses: {}
x-amazon-apigateway-integration:
uri: myFunction.Arn
httpMethod: "POST"
type: "aws_proxy"
/path/two:
post:
responses: {}
x-amazon-apigateway-integration:
uri: myFunction.Arn
httpMethod: "POST"
type: "aws_proxy"
How can I make the path/two an non authenticated route?
I tried to google but there was nothing.
If possible I don't want to create another API Gateway. I would like to do it within the same resource.
As OpenAPI, you can use security: [] to disable auth in some path.
Refer:
https://github.com/zalando/connexion/issues/944
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body
In AWS SAM template, to disable security for specific endpoints in the DefinitionBody, what worked for me is the following:
swagger: "2.0"
info:
title:
Ref: AWS::StackName
paths:
/path/one:
post:
security:
- NONE: []

AWS IAM API Cloudformation help for Access Key/Secret key authorization

We are currently using API Keys to secure access to our API Gateway. However, we are moving to an IAM model with access/secret key. I understand that swagger does not allow us to do this (we currently have api_key set in swagger to enable API Key authentication).
I have created the policy needed for the various operations as:
SvcAccountPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub 'iam-${EnvTag}'
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'execute-api:Invoke'
Resource:
- !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/GET/*'
- !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/POST/*'
- !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/PUT/*'
- !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/DELETE/*'
Users:
- !Ref userSvcAcct
My lambda function is shown below. I am still new to cloud formation, and would love some help on what I can do to add a lambda authorizer to this ( I believe it will be in the Events->ApiPost/Get etc section), that would allow me to use secret/access key.
FtpUserMgmtLambda:
Type: AWS::Serverless::Function
Properties:
Description: Lambda handler function for FTP user management
Handler: 'handler.UserManagementHandler::handleRequest'
Runtime: java8
MemorySize: 512
Timeout: 300
FunctionName: !Ref LambdaFunctionName
Role: !GetAtt UserMgmtLambdaRole.Arn
CodeUri:
Bucket: !Ref LambdaCodeS3Bucket
Key: !Ref LambdaCodeFileName
VpcConfig:
SomeConfig stuff here
Environment:
Variables:
dbPort: !Ref UserStoreDbPort
dbUser: !Ref UserStoreDbUserId
dbName: !Ref UserStoreDbName
environment: !Ref EnvTag
basepath: 'somepath'
Events:
ApiPost:
Type: Api
Properties:
RestApiId: !Ref SomeApi
Path: /path
Method: POST
Auth: <<Dont know what to do here! HELP>>
ApiGet:
Type: Api
Properties:
RestApiId: !Ref SomeApi
Path: /path
Method: GET
Auth: *<<Dont know what to do here! HELP>>*
Tags:
Name: !Ref LambdaFunctionName
function: lambda function that manages ftp users
Fixed this through Swagger. Example code as under:
---
swagger: "2.0"
info:
version: "2017-10-17T17:47:44Z"
title: "User-Mgt-API"
basePath: "/${environment}"
schemes:
- "https"
paths:
/ftpuser:
post:
x-amazon-apigateway-auth:
type: aws_iam
produces:
- "application/json"
responses:
200:
description: "When create user request successful"
schema:
$ref: "#/definitions/Empty"
400:
description: "When API vallidation error happens"
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${FtpUserMgmtLambda.Arn}/invocations
passthroughBehavior: "when_no_match"
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
definitions:
Empty:
type: "object"
title: "Empty Schema"
Then in the cloudformation, added the following to the serverless API definition to process the swagger file. Of course,
FtpUserMgmtApi:
Type: AWS::Serverless::Api
Properties:
Name: !Ref ApiName
StageName: !Ref ApiDeploymentStageName
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: !Sub s3://${swaggerS3Location}
Hope this helps. There is also an example on the web to use x-amazon-apigateway-any-method using which I derived the above. That link is here.

SAM Template : Cognito User Pool integrate in APIgateway - Authorizer doesn't work

I want to integrate Cognito token in my application.
How can i do it in AWS Sam Template ?
To update my template, I look on https://docs.aws.amazon.com/fr_fr/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html?shortFooter=true
Info:
My UserPool is created in the AWS console (on web)
I test with Postman without header: if it worked I should be refused ==> reallity: I have results (my Authorizer doesn't work)
=========================
My question is : why Authorizer doesn't work ?
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Globals:
Function:
Runtime: nodejs6.10
Handler: index.handler
Timeout: 30
Resources:
GRApi:
Type: 'AWS::Serverless::Api'
Properties:
Name: 'Myname'
StageName: !Ref Stage
Cors: "'*'"
EndpointConfiguration: REGIONAL
DefinitionBody:
swagger: "2.0"
info:
version: "1.0"
title: "myTitle"
host: !Ref Host
securityDefinitions:
cognitoUserPool:
type: apiKey
name: Authorization
in: header
x-amazon-apigateway-authtype: cognito_user_pools
x-amazon-apigateway-authorizer:
type: cognito_user_pools
providerARNs:
- "arn:aws:cognito-idp..."
schemes:
- "https"
consumes:
- application/json
produces:
- application/json
paths:
/project:
get:
responses: {}
security:
- cognitoUserPool: []
x-amazon-apigateway-integration:
uri:
- 'arn:aws:apigateway:....Arn'
passthroughBehavior: "when_no_match"
httpMethod: "POST"
type: "aws_proxy"
GetAllProjectsFunction:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: URI/
Handler: index.handler
Runtime: nodejs8.10
MemorySize: 128
Timeout: 30
Role: 'arn:....role'
Events:
GetAllProjects:
Type: Api
Properties:
Path: /project
Method: get
RestApiId: !Ref GRApi
Outputs:
...