API 未调用网关授权器
API Gateway Authorizer is not being called
我创建了一些 Lambda 函数并使用 SAM 部署了它们。部署成功,但在尝试到达端点时我总是获得
{ message: "Unauthorized" }
即使我使用 Authentication
header 发送正确的 Bearer 令牌。
然后,如果我去 Authorizer 并 运行 测试,它会很好地通过并在 CloudWatch 中生成日志,但是当我 运行 从我的前端应用程序或 REST 客户端应用程序到端点的请求时,我得到未经授权的消息并检查 CloudWatch,没有执行授权方功能。
此外,从 Lambda 配置中检查 Authorizer 函数,我可以看到 API Gateway Trigger
中有一个错误,但不知道它是什么意思。
我使用 AWS 提供的指南创建了授权函数:https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html#api-gateway-lambda-authorizer-lambda-function-create
共享我的 SAM 配置
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
关于授权者发回的响应,它发送了API网关
请求的所有参数
{
principalId: decoded.sub,
policyDocument: getPolicyDocument("Allow", params.methodArn),
context: { scope: decoded.scope }
}
我使用的 运行time 是 nodejs12.x
,这里是我从 AWS 控制台获得的一些屏幕截图。
在对互联网上发现的不同内容进行大量测试后,当我注意到政策文件有误时,我开始有所改进:
之前
const policyDocument = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": effect,
"Action": "execute-api:Invoke",
"Resource": resource
}
]
};
之后
const policyDocument = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": effect,
"Action": [
"execute-api:Invoke"
],
"Resource": [
resource
]
}
]
};
其中 Action
和 Resource
应该是数组。此外,我将 resource
变量设置为 '*'
而不是 event.methodArn
,因为在缓存授权时,缓存的策略仅匹配到达的第一个端点,而下一次调用其他端点会导致错误: user not authorized for the method requested
.
其他更改在 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
和 false
值进行预检调用(OPTIONS
),无法验证,因为预检请求是由浏览器完成的,否则所有调用来自 Axios
也失败了。
我有同样的事情。
如果未调用授权方 Lambda,我认为这是因为缓存了身份验证或配置认为请求中没有身份 material。
看看 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_authorizer#identity_source 设置:只有某些 headers 被认为包含身份 material,并且它们被用作缓存键
我创建了一些 Lambda 函数并使用 SAM 部署了它们。部署成功,但在尝试到达端点时我总是获得
{ message: "Unauthorized" }
即使我使用 Authentication
header 发送正确的 Bearer 令牌。
然后,如果我去 Authorizer 并 运行 测试,它会很好地通过并在 CloudWatch 中生成日志,但是当我 运行 从我的前端应用程序或 REST 客户端应用程序到端点的请求时,我得到未经授权的消息并检查 CloudWatch,没有执行授权方功能。
此外,从 Lambda 配置中检查 Authorizer 函数,我可以看到 API Gateway Trigger
中有一个错误,但不知道它是什么意思。
我使用 AWS 提供的指南创建了授权函数:https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html#api-gateway-lambda-authorizer-lambda-function-create
共享我的 SAM 配置
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
关于授权者发回的响应,它发送了API网关
请求的所有参数{
principalId: decoded.sub,
policyDocument: getPolicyDocument("Allow", params.methodArn),
context: { scope: decoded.scope }
}
我使用的 运行time 是 nodejs12.x
,这里是我从 AWS 控制台获得的一些屏幕截图。
在对互联网上发现的不同内容进行大量测试后,当我注意到政策文件有误时,我开始有所改进:
之前
const policyDocument = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": effect,
"Action": "execute-api:Invoke",
"Resource": resource
}
]
};
之后
const policyDocument = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": effect,
"Action": [
"execute-api:Invoke"
],
"Resource": [
resource
]
}
]
};
其中 Action
和 Resource
应该是数组。此外,我将 resource
变量设置为 '*'
而不是 event.methodArn
,因为在缓存授权时,缓存的策略仅匹配到达的第一个端点,而下一次调用其他端点会导致错误: user not authorized for the method requested
.
其他更改在 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
和 false
值进行预检调用(OPTIONS
),无法验证,因为预检请求是由浏览器完成的,否则所有调用来自 Axios
也失败了。
我有同样的事情。 如果未调用授权方 Lambda,我认为这是因为缓存了身份验证或配置认为请求中没有身份 material。
看看 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_authorizer#identity_source 设置:只有某些 headers 被认为包含身份 material,并且它们被用作缓存键