node.js - API 网关返回 401 并且不调用自定义授权方
问题描述
我已经为 API 网关实现了一个自定义的“REQUEST”类型授权器,它验证在“授权”标头中传递的 JWT 令牌。我已经独立测试了 lambda,它按预期工作。我还将授权方附加到我的路由中,我可以在 AWS 控制台中对其进行测试 - 再次,一切似乎都有效(见图):
但是,当我尝试使用Authorization
标头中的令牌调用端点时,我总是收到 UNAUTHORIZED 响应:
{
"errors": [
{
"category": "ClientError",
"code": "UNAUTHORIZED",
"detail": "Unauthorized",
"method": "GET",
"path": "/cases",
"requestId": "004eb254-a926-45ad-96a5-ce3527621c81",
"retryable": false
}
]
}
从我收集到的信息来看,API 网关从不调用我的授权器,因为我在其 cloudwatch 中看不到任何日志事件。我能够启用我的 API 网关的 cloudwatch 日志记录,我看到的唯一日志信息如下:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| timestamp | message |
|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1578275720543 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Extended Request Id: F2v9WFfiIAMF-9w= |
| 1578275720543 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Unauthorized request: dac0d4f6-1380-4049-bcee-bf776ca78e5c |
| 1578275720543 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Extended Request Id: F2v9WFfiIAMF-9w= |
| 1578275720544 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Gateway response type: UNAUTHORIZED with status code: 401 |
| 1578275720544 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Gateway response body: {"errors": [{"category": "ClientError","code": "UNAUTHORIZED","detail": "Unauthorized","method": "GET","path": "/cases","requestId": "dac0d4f6-1380-4049-bcee-bf776ca78e5c","retryable": false }]} |
| 1578275720544 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Gateway response headers: {} |
| 1578275720544 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Gateway response type: UNAUTHORIZED with status code: 401 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在这一点上,我完全被卡住了,不知道如何进一步调试。我假设某些东西必须配置错误,但我能找到的日志信息没有给出任何问题的迹象。我还在下图中粘贴了我的授权人配置的副本:
解决方案
我发现了我遇到的问题:我需要在端点的授权者字段以及 CF 堆栈中设置 identitySource: method.request.header.Authorization。
原始 cloudformation 中的自定义授权者定义:
service:
name: api-base
frameworkVersion: ">=1.2.0 <2.0.0"
plugins:
- serverless-plugin-optimize
- serverless-offline
- serverless-pseudo-parameters
- serverless-domain-manager
custom:
stage: ${self:provider.stage, 'dev'}
serverless-offline:
port: ${env:OFFLINE_PORT, '4000'}
false: false
cognitoStack: marley-auth
customDomain:
domainName: ${env:BE_HOST, ''}
enabled: ${env:EN_CUSTOM_DOMAIN, self:custom.false}
stage: ${self:provider.stage, 'dev'}
createRoute53Record: true
provider:
name: aws
runtime: nodejs10.x
versionFunctions: true
apiName: public
logs:
restApi: true
stackTags:
COMMIT_SHA: ${env:COMMIT_SHA, 'NO-SHA'}
environment:
USER_POOL_ID: ${cf:${self:custom.cognitoStack}-${self:custom.stage}.UserPoolId}
CLIENT_ID: ${cf:${self:custom.cognitoStack}-${self:custom.stage}.UserPoolClientId}
timeout: 30
iamRoleStatements:
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: "*"
functions:
authorizer:
handler: handler/authorize.handler
resources:
- Outputs:
ApiGatewayRestApiId:
Value:
Ref: ApiGatewayRestApi
Export:
Name: ${self:custom.stage}-${self:provider.apiName}-ApiGatewayRestApiId
ApiGatewayRestApiRootResourceId:
Value:
Fn::GetAtt:
- ApiGatewayRestApi
- RootResourceId
Export:
Name: ${self:custom.stage}-${self:provider.apiName}-ApiGatewayRestApiRootResourceId
SharedAuthorizerId:
Value:
Ref: SharedAuthorizer
Export:
Name: ${self:custom.stage}-${self:provider.apiName}-ApiGatewaySharedAuthorizerId
- Resources:
SharedAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: public
AuthorizerUri: !Join
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/'
- !GetAtt
- AuthorizerLambdaFunction
- Arn
- /invocations
RestApiId: !Ref 'ApiGatewayRestApi'
Type: REQUEST
IdentitySource: method.request.header.Authorization
AuthorizerResultTtlInSeconds: '300'
DependsOn: AuthorizerLambdaFunction
ApiAuthLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref AuthorizerLambdaFunction
Principal: apigateway.amazonaws.com
SourceArn: !Sub "arn:aws:execute-api:#{AWS::Region}:#{AWS::AccountId}:#{ApiGatewayRestApi}/authorizers/*"
DependsOn: ApiGatewayRestApi
在另一个堆栈中使用授权者 - 请注意,我已IdentitySource
在此处以及授权者的定义中指定 - 出于某种原因,我不得不在两个地方都这样做。
authorizer:
type: CUSTOM
authorizerId: ${cf:api-base-${self:custom.stage}.SharedAuthorizerId}
identitySource: method.request.header.Authorization
推荐阅读
- c# - 在 C# 中寻找正确的对象表示法来表示 JSON 样式的数据
- python-3.x - python3:将列表列表转换为列表字典
- html - 将几个html文件转换成一个word文件
- python - 发布请求无法在 Robot Framework 中捕获访问令牌
- ruby-on-rails - 将表单中的附加参数添加到连接表中 - has_many 通过
- reactjs - 使用 webpack 构建 bundle.js 时,您在生产模式下已超出此 API 的每日请求配额
- sql-server - 提高 SSIS DFT 的性能
- gulp - Gulp - 按文件夹编译 sass,并修改父目录
- pyspark - pyspark DataFrame selectExpr 不适用于一列以上
- c# - WPF Grid 在 MinWidth 上更改 ColumnSpan