如何将 API Gateway 授权方上下文传递给 HTTP 集成

Posted

技术标签:

【中文标题】如何将 API Gateway 授权方上下文传递给 HTTP 集成【英文标题】:How to pass API Gateway authorizer context to a HTTP integration 【发布时间】:2018-01-19 18:26:14 【问题描述】:

我已成功为我的 AWS API Gateway 实施了 Lambda 授权方,但我想将一些自定义属性从它传递到我的 Node.js 端点。

我的授权人的输出遵循 AWS 指定的格式,如下所示。


  "principalId": "yyyyyyyy",
  "policyDocument": 
    "Version": "2012-10-17",
    "Statement": [
      
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:<regionId>:<accountId>:<appId>/<stage>/<httpVerb>/[<resource>/<httpVerb>/[...]]"
      
    ]
  ,
  "context": 
    "company_id": "123",
    ...
  

在我的例子中,context 包含一些参数,例如 company_id,我想将它们传递给我的节点端点。

如果我要使用 Lambda 端点,我知道这是通过映射模板和类似的东西完成的:


  "company_id": "$context.authorizer.company_id"

但是,如果选择 Lambda 作为集成类型,则正文映射模板仅在集成请求下可用。如果选择了 HTTP,则不会。

简而言之,我如何将company_id 从我的 Lambda 授权方传递到我的 Node API?

【问题讨论】:

如何将这些值放入 HTTP 请求标头中? @Michael-sqlbot 这正是我想做的。标题、网址或正文并不重要。什么都会好的。问题是如何做到这一点? 在集成请求中创建一个标头,然后指定,例如context.identity.whatever 没有 $ 开头。我没有使用自定义授权器,但这对我访问上下文对象中的其他内容并将它们放入转发到源的标头中很有用...例如,我尝试了context.stagecontext.apiId,它们都按预期转发,作为 HTTP 标头。试试看? 此外,“使用 HTTP 代理集成”选项的命名似乎很糟糕。如果您想使用请求正文映射模板...只需取消选中该选项。看起来这个选项实际上意味着“你知道吗?别挡我的路,代理请求,不管它是什么,这样我就可以避免弄乱身体映射模板。”无论是否选中该选项,您都可以将请求代理到后端。 @Michael-sqlbot 谢谢迈克尔!终于在您的回答和aws支持的帮助下让它工作了。我需要将 context.authorizer.company_id 设置为集成请求下的 HTTP 标头 company_id 设置为方法执行下的 HTTP 请求标头。 【参考方案1】:

如果您使用的是lamda-proxy,则可以从您的event.requestContext.authorizer.context 访问上下文。

所以您的company_id 可以使用event.requestContext.authorizer.context.company_id 访问。

【讨论】:

不要使用 lambda 代理,如果可能的话我想避免它。 奇怪的是,如果我使用普通的 lambda 集成,$context.authorizer 是空的,所以我找不到通过主体映射将该信息传递给 lambda 的方法。我在 API GW 中使用 REST api 并使用 cognito 作为授权方。【参考方案2】:

大部分功劳归于我的问题的 cmets 中的 @Michael-sqlbot,但如果其他人发现这个问题,我会将完整的答案放在这里。

授权者 Lambda

它必须以这种格式返回一个对象,其中 context 包含您要转发到端点的参数,如问题中所述。


  "principalId": "yyyyyyyy",
  "policyDocument": 
    "Version": "2012-10-17",
    "Statement": [
      "Action": "execute-api:Invoke",
      "Effect": "Allow|Deny",
      "Resource": "arn:aws:execute-api:<regionId>:<accountId>:<appId>/<stage>/<httpVerb>/[<resource>/<httpVerb>/[...]]"
    ]
  ,
  "context": 
    "company_id": "123", <-- The part you want to forward
    ...
  

方法请求

在 Method Request / HTTP Request Headers 下,添加要转发的上下文属性:

姓名:company_id 必需:可选 兑现:可选

集成请求

在集成请求/HTTP标头下,添加:

姓名:company_id 映射自:context.authorizer.company_id 兑现:可选

【讨论】:

我认为这是 AWS Service Integration 中一个强大的未记录(至少帮助中没有列出)功能。 我认为不需要在“方法请求”中添加标头 非常感谢。为我节省了很多时间。正如@Rich 所说,“方法请求”中不需要标头 @Magnus-Engdal - 感谢您花时间记录完整的答案。它对我有用。 你终于设法让它工作了吗?我按照步骤操作,但我不断看到event.headers == undefined

以上是关于如何将 API Gateway 授权方上下文传递给 HTTP 集成的主要内容,如果未能解决你的问题,请参考以下文章

如何使用无服务器部署没有身份源的 API Gateway 自定义授权方?

在 API Gateway 中使用 AWS Lambda 授权方

如何将查询参数传递给 Rails API 控制器?

如何为 AWS API Gateway 自定义授权方配置 CORS?

AWS API Gateway 自定义授权方有用吗?

未调用 AWS API Gateway 自定义授权方