【问题标题】:Allow Guest Mode (no authorization) in Custom Authorizer in AWS在 AWS 的自定义授权器中允许访客模式(无授权)
【发布时间】:2021-12-30 06:15:27
【问题描述】:

我正在尝试找到一种方法来在 AWS 的自定义授权方中允许 访客模式

基本上,我想要实现的是以下场景:

  • 如果请求中没有 Authorization 标头,则触发响应一些数据的 lambda 函数
  • 如果有Authorization 标头,那么我的自定义授权者应该检查JWT 令牌和AllowDeny。如果custom-authorizer 返回Allow,则触发 lambda

我知道我可以实现其中一个但不能同时实现,即我可以打开端点(完全删除 authorizer),它可以正常工作,或者我可以输入authorizer,它又可以正常工作。

但是,当没有 Authorization 标头时,我看不到绕过 custom-authorizer 的方法。

无服务器中的示例配置:

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: /hello
          method: get
          private: true
          authorizer:
            identitySource: method.request.header.Authorization # Can this be optional?
            name: custom-authorizer
  custom-authorizer:
    handler: authorizer.handler

根据我的测试,我可以确认,一旦存在authorization 并且请求中没有Authorization 标头,那么我的custom-authorizer 根本不会被触发,API 网关会立即响应401 Unauthorized

请注意,在我的访客模式下,我想要获得自定义 API 网关响应(这是可能的并且有效)。我想触发 lambda 函数,就像根本没有授权一样。

我得出结论这是不可能的,唯一的解决方法是删除authorization,然后在 lambda 中执行一些自定义代码。

有什么建议吗?

【问题讨论】:

    标签: amazon-web-services aws-lambda authorization serverless sls


    【解决方案1】:

    如果您将sls event handler 配置为httpApi*,而不是http,则identitySourceauthorizer 的可选输入(假设无服务器api 匹配AWS api )。

    相关的 CloudFormation AWS::ApiGatewayV2::Authorizer 文档是 here

    如您所见,如果 identitySource 已配置但未出现在客户端请求中,Apig 将返回 401。如果您在配置中省略 identitySource,所有请求都将发送到您的授权者 lambda。然后,您的 lambda 可以处理三种情况:无令牌、坏令牌、好令牌。

    *httpApi 在 AWS CloudFormation 中部署为 ApiGatewayV2。正如 Serverless 文档所说,V2“比 v1 更快、更便宜”。 api 和 feature set 在 "HTTP Api" (V2) "Rest Api" (V1) 之间略有不同,但 httpApi 是一个不错的默认选择。

    【讨论】:

    • 这个httpApi 看起来很有前途。然而,从httphttpApi 的简单更改会导致Event references not configured authorizer 'custom-authorizer' 错误。似乎需要进行更多配置更改。总的来说,很好的提示!
    • 越来越多的人注意到httpApi 有一个更新的语法:github.com/serverless/serverless/issues/…
    【解决方案2】:

    在这里跟进@fedonev 的回答是完整的解决方案:

    • 使用HTTP API 而不是REST API
    • 更新custom-authorizer

    让我们从更新serverless.yml 开始,使其适应更新的不同 HTTP API 语法:

    events.http 替换为events.httpApi 并将httpApi.authorizer 添加到provider。更新serverless.yml

    provider:
      httpApi:                          # Added
        authorizers:
          customAuthorizer:
            type: request
            functionName: custom-authorizer
    
    functions:
      hello:
        handler: handler.hello
        events:
          - httpApi:                    # Changed
              path: /hello
              method: get
              authorizer:
                name: customAuthorizer  # Changed
    
    custom-authorizer:
      handler: authorizer.handler
    

    接下来,我们还需要更新我们的授权处理函数。它仍然需要像使用 REST API 一样返回策略。然而...没有event.authorizationToken 也没有event.methodArn 了(我把它注释掉以供参考):

    module.exports.handler = async (event) => {
      if (
        !event.headers.authorization ||
        event.headers.authorization === 'Bearer ABCDEF'
      ) {
        // if (event.authorizationToken === 'Bearer ABCDEF')
        return {
          principalId: 'anonymous',
          policyDocument: {
            Version: '2012-10-17',
            Statement: [
              {
                Action: 'execute-api:Invoke',
                Effect: 'Allow',
                Resource: event.routeArn,
                // Resource: event.methodArn,
              },
            ],
          },
        };
      }
      throw Error('Unauthorized');
    };
    

    现在,我们可以看到我们可以完全控制授权,我们可以检查令牌是否存在:!event.headers.authorization(这模拟访客模式)或令牌是否有效:event.headers.authorization === 'Bearer ABCDEF'。如果令牌无效,我们会抛出错误,如预期的那样给出401 Unauthorized

    最后,值得注意的是所有headers 键都是小写的,principalId 是强制性的(如前所述,在使用 REST API 时,授权方在没有它的情况下工作)。

    部署并享受!

    【讨论】:

      猜你喜欢
      • 2021-01-12
      • 1970-01-01
      • 2015-12-13
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-14
      相关资源
      最近更新 更多