Skip to content

Instantly share code, notes, and snippets.

@evankirkiles
Created March 7, 2022 06:09
Show Gist options
  • Save evankirkiles/9de81f026a2e2c961a2b6a3d80d35519 to your computer and use it in GitHub Desktop.
Save evankirkiles/9de81f026a2e2c961a2b6a3d80d35519 to your computer and use it in GitHub Desktop.
Cognito User Pool Auth for AWS Amplify Function CFN Override
// This file is used to override the REST API resources configuration
import { AmplifyApiRestResourceStackTemplate } from "@aws-amplify/cli-extensibility-helper";
export function override(resources: AmplifyApiRestResourceStackTemplate) {
// Add our user pool id as a parameter so we can create authorizers with it
// Note that you have to replace <your auth name here> with the name of your auth!
// It's the name of the folder in amplify/backend/auth that was created when you
// added the auth to the project (NOT userPoolGroups). Also make sure you keep
// the preceding "auth" part of the string before the auth name, it's necessary.
resources.addCfnParameter(
{
type: "String",
description:
"The id of an existing User Pool to connect. If this is changed, a user pool will not be created for you.",
default: "NONE",
},
"AuthCognitoUserPoolId",
{
"Fn::GetAtt": ["auth<your auth name here>", "Outputs.UserPoolId"],
}
);
// create the authorizer using the AuthCognitoUserPoolId parameter defined above
resources.restApi.addPropertyOverride("Body.securityDefinitions", {
Cognito: {
type: "apiKey",
name: "Authorization",
in: "header",
"x-amazon-apigateway-authtype": "cognito_user_pools",
"x-amazon-apigateway-authorizer": {
type: "cognito_user_pools",
providerARNs: [
{
"Fn::Join": [
"",
[
"arn:aws:cognito-idp:",
{
Ref: "AWS::Region",
},
":",
{
Ref: "AWS::AccountId",
},
":userpool/",
{
Ref: "AuthCognitoUserPoolId",
},
],
],
},
],
},
},
});
// for each path in the rest API, add the authorizer for all methods
for (const path in resources.restApi.body.paths) {
// add the Authorization header as a parameter to the rest API for the path
resources.restApi.addPropertyOverride(
`Body.paths.${path}.x-amazon-apigateway-any-method.parameters`,
[
...resources.restApi.body.paths[path]["x-amazon-apigateway-any-method"]
.parameters,
{
name: "Authorization",
in: "header",
required: false,
type: "string",
},
]
);
// set the security method to use our user pool authorizer
// TODO: do we need to destructure the other security methods as well?
resources.restApi.addPropertyOverride(
`Body.paths.${path}.x-amazon-apigateway-any-method.security`,
[
{
Cognito: [],
},
]
);
}
}
@evankirkiles
Copy link
Author

evankirkiles commented May 6, 2022

Hey @evankirkiles 👋 would you be open to adding this as an example to the AWS Amplify documentation site? https://github.com/aws-amplify/docs

@josefaidt Yeah, of course! Here's a PR: aws-amplify/docs#4282

@kagetora0924
Copy link

kagetora0924 commented Jun 5, 2023

@evankirkiles
// for each path in the rest API, add the authorizer for all methods
is it possible to add the authorizer for only several methods?
I want to add it just for GET method.

@evankirkiles
Copy link
Author

@kagetora0924 Yes, this is possible as well! You just need to replace the x-amazon-apigateway-any-method substring on lines 59, 51, and 74 with the type of request you want the authorizer on. For example, if you wanted the authorizer on POST requests only, you'd write something like:

# lines 58-59
    resources.restApi.addPropertyOverride(
-      `Body.paths.${path}.x-amazon-apigateway-any-method.parameters`,
+      `Body.paths.${path}.post.parameters`,

everywhere where x-amazon-apigateway-any-method occurs. For multiple methods, you'd likely need to run this separately for every method, as each method has its own section of parameters in the OpenAPI / Swagger spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment