无服务器授权请求未提供methodArn,也没有关于调用lambda的任何信息。

huangapple go评论86阅读模式
英文:

Serverless authorizer request does not provide methodArn, or any information about the calling lambda

问题

我在定义的授权者 Lambda 函数中遇到了从请求对象中获取 methodArn 的问题。我正在使用使用 Golang 的 Serverless。以下是我代码的简化版本。

main.go - 授权者处理函数

func Handler(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
  // 我尝试将整个请求记录到 CloudWatch,下面有示例

  // 这里有代码来验证 JWT 令牌
  return nil, nil
}

serverless.yml - 我的 Serverless 配置,用于注册函数和定义授权者

functions:
  permission_verify:
    handler: bin/handlers/permission/verify

package:
  patterns:
    - "!./**"
    - ./bin/**

provider:
  httpApi:
    authorizers:
      custom:
        functionName: permission_verify
        type: request

通过上述设置,我能够在其他微服务中使用授权者来验证 JWT 令牌,但现在我想为授权者添加更多功能,为此我需要请求中的 methodArn 存在。

下面是在调用使用授权者的端点后 CloudWatch 的输出。

CloudWatch - 请求的 JSON

{
    "type": "REQUEST",
    "methodArn": "",
    "resource": "",
    "path": "",
    "httpMethod": "",
    "headers": {
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br",
        "authorization": "redacted",
        "content-length": "redacted",
        "content-type": "application/json",
        "host": "redacted",
        "postman-token": "redacted",
        "user-agent": "PostmanRuntime/7.31.3",
        "x-amzn-trace-id": "redacted",
        "x-forwarded-for": "redacted",
        "x-forwarded-port": "443",
        "x-forwarded-proto": "https"
    },
    "queryStringParameters": null,
    "pathParameters": null,
    "stageVariables": null,
    "requestContext": {
        "path": "",
        "accountId": "redacted",
        "resourceId": "",
        "stage": "$default",
        "requestId": "redacted",
        "identity": {
            "apiKey": "",
            "sourceIp": ""
        },
        "resourcePath": "",
        "httpMethod": "",
        "apiId": "redacted"
    }
}

我已经在互联网上搜索了很多,但没有找到关于请求中没有关于调用 Lambda 的信息的解释和原因。已经过了相当长的时间,任何帮助将不胜感激。

英文:

I am having issues getting the methodArn from a request object in an authorizer lambda I have defined. I am using serverless with golang. Here is a redacted setup of the code that I have.

main.go - the authorizer handler function

func Handler(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
  // I have tried logging the entire request to cloud watch, see further down for the sample

  // i have code here to verify a jwt token
  return nil, nil
}

serverless.yml - my serverless setup to register the function and define the authorizer

functions:
  permission_verify:
    handler: bin/handlers/permission/verify

package:
  patterns:
    - "!./**"
    - ./bin/**

provider:
  httpApi:
    authorizers:
      custom:
        functionName: permission_verify
        type: request

With the above setup I am able to use the authorizer in other microservices to verify jwt tokens but now I would like to add more functionality to the authorizer and with that I need the methodArn on the request to be present.

Here is the output from cloud watch after hitting an endpoint that uses the authorizer

cloud watch - the request json

{
    "type": "REQUEST",
    "methodArn": "",
    "resource": "",
    "path": "",
    "httpMethod": "",
    "headers": {
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br",
        "authorization": "redacted",
        "content-length": "redacted",
        "content-type": "application/json",
        "host": "redacted",
        "postman-token": "redacted",
        "user-agent": "PostmanRuntime/7.31.3",
        "x-amzn-trace-id": "redacted",
        "x-forwarded-for": "redacted",
        "x-forwarded-port": "443",
        "x-forwarded-proto": "https"
    },
    "queryStringParameters": null,
    "pathParameters": null,
    "stageVariables": null,
    "requestContext": {
        "path": "",
        "accountId": "redacted",
        "resourceId": "",
        "stage": "$default",
        "requestId": "redacted",
        "identity": {
            "apiKey": "",
            "sourceIp": ""
        },
        "resourcePath": "",
        "httpMethod": "",
        "apiId": "redacted"
    }
}

I have scoured the internet looking for an explanation and cause for having no information about the calling lambda in the request to no avail. It has been quite a bit of time, any help would be immensely appreciated.

答案1

得分: 1

我找到了一个解决方案,使用REST而不是HTTP。我不得不重新编写所有的函数,并像下面这样定义无服务器;

serverless.yaml

custom:
  authorizer:
    type: token
    identitySource: method.request.header.Authorization
    identityValidationExpression: Bearer (.*)
    name: permission_verify
    # if this is in a different service, you can replace the name property with 'arn' having the arn of the function

functions:
  permission_verify:
    handler: bin/handlers/permission/verify

  permission_read:
    events:
      -http: # i had httpApi before
        method: get
        path: /
        authorizer: ${self:custom.authorizer}

这使我能够将函数签名更改为以下内容,并在检查云监控日志后,我能够获取方法 ARN。

func Handler(request events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error)

这是我在云监控中得到的一个例子;

{
    "type": "TOKEN",
    "authorizationToken": "Bearer <redacted>",
    "methodArn": "arn:aws:execute-api:us-east-1:redacted/PUT/"
}

总之,造成这个问题的原因只是不一致的无服务器配置,不符合我所需的目的。我认为,无服务器是一种定义基础架构的简单方法,但它并不是完美无缺的,了解你要做什么以及提供了什么是很重要的。

英文:

I found a solution that worked using REST instead of HTTP. I had to redo all my functions and define the serverless like the following;

serverless.yaml

custom:
  authorizer:
    type: token
    identitySource: method.request.header.Authorization
    identityValidationExpression: Bearer (.*)
    name: permission_verify
    # if this is in a different service, you can replace the name property with &#39;arn&#39; having the arn of the function

functions:
  permission_verify:
    handler: bin/handlers/permission/verify

  permission_read:
    events:
      -http: # i had httpApi before
        method: get
        path: /
        authorizer: ${self:custom.authorizer}

This allowed me to change the function signature to something like below, and after checking the cloud watch logs, I was able to get the method ARN.

func Handler(request events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error)

Here is an example of what I got in cloud watch;

{
    &quot;type&quot;: &quot;TOKEN&quot;,
    &quot;authorizationToken&quot;: &quot;Bearer &lt;redacted&gt;&quot;,
    &quot;methodArn&quot;: &quot;arn:aws:execute-api:us-east-1:redacted/PUT/&quot;
}

In summary, the cause of this was just inconsistent serverless config that did not fit the purpose of what I required. I'd say IMO, it is easy to think that serverless is a fool proof way of defining infrastructure but it's not and it's good to understand what you're going for against what is offered.

答案2

得分: 0

我很确定应该是这样的:

func Handler(request events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error) {

而不是

func Handler(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {

请参考 https://github.com/serverless/examples/blob/master/aws-golang-auth-examples/functions/auth/main.go 中的一个可行示例。

英文:

I'm pretty sure it should be

func Handler(request events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error) {

and not

func Handler(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {

See https://github.com/serverless/examples/blob/master/aws-golang-auth-examples/functions/auth/main.go for a working example

答案3

得分: 0

不确定你的 serverless.yml 文件是什么样子的,但这可能是一个很好的例子。

service: your-service

provider:
  name: aws
  runtime: go1.x
  httpApi:
    payload: '2.0'

functions:
  permission_verify:
    handler: bin/handlers/permission/verify
  your_protected_function:
    handler: bin/handlers/your_protected_function
    events:
      - httpApi:
          method: any # 或者你想允许的具体 HTTP 方法
          path: /your_path
          authorizer:
            name: custom

custom:
  authorizers:
    custom:
      functionName: permission_verify
      type: request

package:
  patterns:
    - "!./**"
    - ./bin/**

确保在 Go 代码中,使用 events.APIGatewayCustomAuthorizerRequest 类型而不是 events.APIGatewayCustomAuthorizerRequestTypeRequest 作为请求参数:

func Handler(request events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error) {}
英文:

not sure how your serverless.yml file looks like, but this could be a good example in case.

service: your-service

provider:
  name: aws
  runtime: go1.x
  httpApi:
    payload: &#39;2.0&#39;

functions:
  permission_verify:
    handler: bin/handlers/permission/verify
  your_protected_function:
    handler: bin/handlers/your_protected_function
    events:
      - httpApi:
          method: any # or the specific HTTP method you want to allow
          path: /your_path
          authorizer:
            name: custom

custom:
  authorizers:
    custom:
      functionName: permission_verify
      type: request

package:
  patterns:
    - &quot;!./**&quot;
    - ./bin/**

make sure that you are using the
events.APIGatewayCustomAuthorizerRequest
type instead of
events.APIGatewayCustomAuthorizerRequestTypeRequest
for the request parameter in the Go code:

func Handler(request events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error) {}

huangapple
  • 本文由 发表于 2023年3月29日 15:28:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75874335.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定