skip to Main Content

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.

3

Answers


  1. Chosen as BEST ANSWER

    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 '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}
    

    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;

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

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

    Login or Signup to reply.
  3. 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: '2.0'
    
    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:
        - "!./**"
        - ./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) {}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search