具有 Cognito 用户池授权方的 AWS SAM API
Posted
技术标签:
【中文标题】具有 Cognito 用户池授权方的 AWS SAM API【英文标题】:AWS SAM API with Cognito User Pools authorizer 【发布时间】:2018-01-24 19:22:15 【问题描述】:如何使用AWS SAM 创建一个使用 Cognito 用户池授权方进行授权的 API?
有AWS::ApiGateway::Authorizer。但是……
"Type" : "AWS::ApiGateway::Authorizer",
"Properties" :
"AuthorizerCredentials" : String,
"AuthorizerResultTtlInSeconds" : Integer,
"AuthorizerUri" : String,
"IdentitySource" : String,
"IdentityValidationExpression" : String,
"Name" : String,
"ProviderARNs" : [ String, ... ],
"RestApiId" : String,
"Type" : String
看起来RestApiId 指的是使用这个授权者的API?但是使用 AWS SAM,我的 API 定义为
Resources:
Ec2Index:
Type: AWS::Serverless::Function
Properties:
Handler: ec2/index.handler
Runtime: nodejs6.10
CodeUri: ./src
FunctionName: 'ApiEc2IndexHandler'
Description: 'List EC2 resources'
Timeout: 30
Role: 'arn:aws:iam::598545985414:role/awsmanagement-lambda-management'
Events:
Ec2Index:
Type: Api
Properties:
Path: /ec2
Method: get
我不明白如何将它们关联在一起?
【问题讨论】:
如果没有 Swagger 模型(显式路线),今天这是不可能的。但是,这里正在跟踪此功能和其他功能:github.com/awslabs/serverless-application-model/issues/248。希望很快我们可以完全依赖隐式 API 定义! @jiew-meng 简而言之,使用 API Authorizer Object 为您的 API 定义一个 Cognito Authorizer。然后,将您的 lambda 函数的 Auth 设置为引用此 API。您可以参考link.medium.com/X6GaTwUjWX了解更多信息。 【参考方案1】:从 AWS SAM v1.8.0 开始,您可以使用以下语法来执行此操作。您可以参考this article 了解更多信息。
简而言之,使用 API Authorizer Object 为您的 API 定义一个 Cognito Authorizer。然后,将您的 lambda 函数的 Auth 设置为引用此 API。
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Auth:
DefaultAuthorizer: MyCognitoAuth # OPTIONAL
Authorizers:
MyCognitoAuth:
# Can also accept an array
UserPoolArn: !GetAtt MyCognitoUserPool.Arn
Identity: # OPTIONAL
# OPTIONAL; Default: 'Authorization'
Header: MyAuthorizationHeader
# OPTIONAL
ValidationExpression: myAuthValidationExp
MyFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: MyFunction
...
Events:
Post:
Type: Api
Properties:
Path: /compute
Method: POST
RestApiId: !Ref MyApi
Auth:
Authorizer: MyCognitoAuth
【讨论】:
【参考方案2】:您可以将您的 Cognito 用户授权者直接添加到您的 SAM AWS::Serverless::Api
。
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Cors: "'*'"
Auth:
DefaultAuthorizer: MyCognitoAuthorizer
Authorizers:
MyCognitoAuthorizer:
UserPoolArn: 'arn:aws:cognito-.....' # YOUR COGNITO USER POOL ARN
如果你没有设置默认的,你可以在你的AWS::Serverless::Function
上添加一个函数授权者。或者您可以使用Authorizer: 'NONE'
将其停用。
Auth:
Authorizer: MyCognitoAuthorizer
另见documentation。
【讨论】:
为什么需要Authorized in the Function?这是必要的还是仅仅在 API 中创建一个授权方就足够了? 在函数中添加Authorizer
key 如果你将它添加到API资源中,它并不是真正需要的。但是,请记住将RestApiId
添加到函数中。【参考方案3】:
正如@simones 提到的,以下将创建 Cognito 用户池授权方(CF 模板)。
ApiCognitoAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
IdentitySource: 'method.request.header.Authorization'
Name: ApiCognitoAuthorizer
ProviderARNs:
- 'arn:aws:cognito-idp:region:userpoolIdentifier'
RestApiId: !Ref ServerlessRestApi
Type: COGNITO_USER_POOLS
要将其附加到资源方法,以下工作(在 Swagger 文件中):
securityDefinitions:
ApiCognitoAuthorizer:
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:region:userpoolIdentifier
然后,添加到特定方法(在 Swagger 文件中):
security:
- ApiCognitoAuthorizer: []
【讨论】:
【参考方案4】:您现在可以使用“ServerlessRestApi”引用隐式创建的 api 网关。 因此,在您的 SAM 模板中添加这段常规 Cloudformation,一切都会正常运行
ApiCognitoAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
IdentitySource: 'method.request.header.Authorization'
Name: ApiCognitoAuthorizer
ProviderARNs:
- 'arn:aws:cognito-idp:region:userpoolIdentifier'
RestApiId: !Ref ServerlessRestApi
Type: COGNITO_USER_POOLS
【讨论】:
这正确地将认知授权者附加到网关,但是有没有办法将其作为授权者分配给 SAM 模板中的特定功能?【参考方案5】:我不确定您是否可以在 SAM 中指定授权人,但您可以将 Swagger 嵌入可以执行此操作的 SAM 文件中。这是 2 月 17 日的新功能 [ref]。
我绝对不是 Swagger 或 SAM 方面的专家,但您似乎想要这样的东西:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Simple API Endpoint configured using Swagger specified inline and backed by a Lambda function
Resources:
Ec2Index:
Type: AWS::Serverless::Api
Properties:
StageName: <stage>
DefinitionBody:
swagger: 2.0
info:
title:
Ref: AWS::StackName
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:$AWS::Region:AWS::AccountId:userpool/<user_pool_id>
paths:
"/ec2":
get:
security:
- cognitoUserPool: []
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:$AWS::Region:lambda:path/2015-03-31/functions/$Ec2IndexLamb.Arn/invocations
responses:
swagger: '2.0'
Ec2IndexLamb:
Type: AWS::Serverless::Function
Properties:
Handler: ec2/index.handler
Runtime: nodejs6.10
CodeUri: ./src
FunctionName: 'ApiEc2IndexHandler'
Description: 'List EC2 resources'
Timeout: 30
Role: 'arn:aws:iam::598545985414:role/awsmanagement-lambda-management'
Events:
Ec2Index:
Type: Api
Properties:
Path: /ec2
Method: get
参考资料:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html#apigateway-enable-cognito-user-pool
https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/inline_swagger/template.yaml
编辑:修复了“安全”部分的 Swagger 2.0 语法,它应该是一个列表。
【讨论】:
以上是关于具有 Cognito 用户池授权方的 AWS SAM API的主要内容,如果未能解决你的问题,请参考以下文章
使用多个用户池的具有 Cognito 授权的 AWS API 网关
AWS API Gateway + Cognito 用户池授权方 + Lambda - 我需要设置哪些 HTTP 标头和权限?
如何在 API 网关上的 cognito 授权方保护的 lambda 函数中获取 AWS Cognito 用户数据
AWS Cognito:Cognito 用户池的元数据 URL 在哪里?