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

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

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

问题

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

main.go - 授权者处理函数

  1. func Handler(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
  2. // 我尝试将整个请求记录到 CloudWatch,下面有示例
  3. // 这里有代码来验证 JWT 令牌
  4. return nil, nil
  5. }

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

  1. functions:
  2. permission_verify:
  3. handler: bin/handlers/permission/verify
  4. package:
  5. patterns:
  6. - "!./**"
  7. - ./bin/**
  8. provider:
  9. httpApi:
  10. authorizers:
  11. custom:
  12. functionName: permission_verify
  13. type: request

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

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

CloudWatch - 请求的 JSON

  1. {
  2. "type": "REQUEST",
  3. "methodArn": "",
  4. "resource": "",
  5. "path": "",
  6. "httpMethod": "",
  7. "headers": {
  8. "accept": "*/*",
  9. "accept-encoding": "gzip, deflate, br",
  10. "authorization": "redacted",
  11. "content-length": "redacted",
  12. "content-type": "application/json",
  13. "host": "redacted",
  14. "postman-token": "redacted",
  15. "user-agent": "PostmanRuntime/7.31.3",
  16. "x-amzn-trace-id": "redacted",
  17. "x-forwarded-for": "redacted",
  18. "x-forwarded-port": "443",
  19. "x-forwarded-proto": "https"
  20. },
  21. "queryStringParameters": null,
  22. "pathParameters": null,
  23. "stageVariables": null,
  24. "requestContext": {
  25. "path": "",
  26. "accountId": "redacted",
  27. "resourceId": "",
  28. "stage": "$default",
  29. "requestId": "redacted",
  30. "identity": {
  31. "apiKey": "",
  32. "sourceIp": ""
  33. },
  34. "resourcePath": "",
  35. "httpMethod": "",
  36. "apiId": "redacted"
  37. }
  38. }

我已经在互联网上搜索了很多,但没有找到关于请求中没有关于调用 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

  1. func Handler(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
  2. // I have tried logging the entire request to cloud watch, see further down for the sample
  3. // i have code here to verify a jwt token
  4. return nil, nil
  5. }

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

  1. functions:
  2. permission_verify:
  3. handler: bin/handlers/permission/verify
  4. package:
  5. patterns:
  6. - "!./**"
  7. - ./bin/**
  8. provider:
  9. httpApi:
  10. authorizers:
  11. custom:
  12. functionName: permission_verify
  13. 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

  1. {
  2. "type": "REQUEST",
  3. "methodArn": "",
  4. "resource": "",
  5. "path": "",
  6. "httpMethod": "",
  7. "headers": {
  8. "accept": "*/*",
  9. "accept-encoding": "gzip, deflate, br",
  10. "authorization": "redacted",
  11. "content-length": "redacted",
  12. "content-type": "application/json",
  13. "host": "redacted",
  14. "postman-token": "redacted",
  15. "user-agent": "PostmanRuntime/7.31.3",
  16. "x-amzn-trace-id": "redacted",
  17. "x-forwarded-for": "redacted",
  18. "x-forwarded-port": "443",
  19. "x-forwarded-proto": "https"
  20. },
  21. "queryStringParameters": null,
  22. "pathParameters": null,
  23. "stageVariables": null,
  24. "requestContext": {
  25. "path": "",
  26. "accountId": "redacted",
  27. "resourceId": "",
  28. "stage": "$default",
  29. "requestId": "redacted",
  30. "identity": {
  31. "apiKey": "",
  32. "sourceIp": ""
  33. },
  34. "resourcePath": "",
  35. "httpMethod": "",
  36. "apiId": "redacted"
  37. }
  38. }

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

  1. custom:
  2. authorizer:
  3. type: token
  4. identitySource: method.request.header.Authorization
  5. identityValidationExpression: Bearer (.*)
  6. name: permission_verify
  7. # if this is in a different service, you can replace the name property with 'arn' having the arn of the function
  8. functions:
  9. permission_verify:
  10. handler: bin/handlers/permission/verify
  11. permission_read:
  12. events:
  13. -http: # i had httpApi before
  14. method: get
  15. path: /
  16. authorizer: ${self:custom.authorizer}

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

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

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

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

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

英文:

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

  1. custom:
  2. authorizer:
  3. type: token
  4. identitySource: method.request.header.Authorization
  5. identityValidationExpression: Bearer (.*)
  6. name: permission_verify
  7. # if this is in a different service, you can replace the name property with &#39;arn&#39; having the arn of the function
  8. functions:
  9. permission_verify:
  10. handler: bin/handlers/permission/verify
  11. permission_read:
  12. events:
  13. -http: # i had httpApi before
  14. method: get
  15. path: /
  16. 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.

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

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

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

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

我很确定应该是这样的:

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

而不是

  1. 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

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

and not

  1. 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 文件是什么样子的,但这可能是一个很好的例子。

  1. service: your-service
  2. provider:
  3. name: aws
  4. runtime: go1.x
  5. httpApi:
  6. payload: '2.0'
  7. functions:
  8. permission_verify:
  9. handler: bin/handlers/permission/verify
  10. your_protected_function:
  11. handler: bin/handlers/your_protected_function
  12. events:
  13. - httpApi:
  14. method: any # 或者你想允许的具体 HTTP 方法
  15. path: /your_path
  16. authorizer:
  17. name: custom
  18. custom:
  19. authorizers:
  20. custom:
  21. functionName: permission_verify
  22. type: request
  23. package:
  24. patterns:
  25. - "!./**"
  26. - ./bin/**

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

  1. 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.

  1. service: your-service
  2. provider:
  3. name: aws
  4. runtime: go1.x
  5. httpApi:
  6. payload: &#39;2.0&#39;
  7. functions:
  8. permission_verify:
  9. handler: bin/handlers/permission/verify
  10. your_protected_function:
  11. handler: bin/handlers/your_protected_function
  12. events:
  13. - httpApi:
  14. method: any # or the specific HTTP method you want to allow
  15. path: /your_path
  16. authorizer:
  17. name: custom
  18. custom:
  19. authorizers:
  20. custom:
  21. functionName: permission_verify
  22. type: request
  23. package:
  24. patterns:
  25. - &quot;!./**&quot;
  26. - ./bin/**

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

  1. 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:

确定