serverless / serverless

⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.
https://serverless.com
MIT License
46.66k stars 5.74k forks source link

Authorizer context not passed to lambda function for SimpleResponse authorizer #10463

Open oddanderson opened 3 years ago

oddanderson commented 3 years ago

Are you certain it's a bug?

Is the issue caused by a plugin?

Are you using the latest version?

Is there an existing issue for this?

Issue description

I set up a simple response authorizer like so:

provider:
  ...
  httpApi:
    authorizers:
      verify_token:
        type: request
        functionName: verify_token
        resultTtlInSeconds: 300
        enableSimpleResponses: true
        payloadVersion: '2.0'
        identitySource:
          - $request.header.Authorization

and return a context in my authorizer like so:

let authResult = {
            "isAuthorized": true,
            "context": {
                "email": decoded.email,
                "user_id": decoded.user_id,
            }
        };
return callback(null, authResult);

However, the context is not getting passed into my lambda function. I saw that this was supposed to be addressed here: https://github.com/serverless/serverless/pull/4773 but perhaps that only works for authorizers with Policy responses and not simple responses?

Service configuration (serverless.yml) content

provider:
  ...
  httpApi:
    authorizers:
      verify_token:
        type: request
        functionName: verify_token
        resultTtlInSeconds: 300
        enableSimpleResponses: true
        payloadVersion: '2.0'
        identitySource:
          - $request.header.Authorization

functions:
  verify_token:
    handler: auth.verify_token
  update_contacts:
    handler: contacts.update_contacts
    events:
      - httpApi: 
          path: /users/update_contacts
          method: post 
          authorizer: verify_token

Command name and used flags

N/A

Command output

N/A

Environment information

Framework Core: 2.70.0 (local)
Plugin: 5.5.2
SDK: 4.3.0
Components: 3.18.1
pgrzesik commented 3 years ago

Hello @oddanderson - thanks for reporting and sorry you've run into trouble. I've tried to reproduce your specific issue and I see the context passed to handler Lambda - it's accessible under event.requestContext.authorizer.lambda. Could you confirm that's the case in your example as well?

oddanderson commented 3 years ago

hi @pgrzesik - yes I see it now. In non serverless world, is it always the "lambda" property that gets populated? Would be helpful to augment the serverless docs with the property that gets populated when setting context variables. Admittedly, I couldn't find a single resource on either AWS or Serverless that tells you how to access a variable from authorizer's context

pgrzesik commented 3 years ago

Hello @oddanderson - it's hard to map it to a non-serverless world as event is specific to Lambda in this case. As for the docs update - we'd be happy to accept a clarification in form of PR 💯

jega-ms commented 3 years ago

i'm facing similar issue for custom authorizer.

when we use sls offline, LambdaProxyIntegrationEventV2.requestContext.authorizer response format is complete different from productions version. So could not use my offline options.

Could you please check & let me know if any workaround is there for this issue ?

Aws Console log ( LambdaProxyIntegrationEventV2.requestContext)


{
    "accountId": "079769519752",
        "apiId": "domainPrefix",
            "authorizer": {
        "lambda": {
            "id": "grQA30BuMSYhxUGoU7R9o85z52R2",
                "role": "user"
        }
    },
    "domainName": "domainPrefix.execute-api.us-east-2.amazonaws.com",
        "domainPrefix": "domainPrefix",
            "http": {
        "method": "POST",
            "path": "/users/login",
                "protocol": "HTTP/1.1",
                    "sourceIp": "157.46.126.34",
                        "userAgent": "PostmanRuntime/7.29.0"
    },
    "requestId": "N7PpwgflCYcEJjQ=",
        "routeKey": "POST /users/{proxy+}",
            "stage": "$default",
                "time": "22/Feb/2022:04:00:23 +0000",
                    "timeEpoch": 1645502423895
}

Serverless Offline Response(LambdaProxyIntegrationEventV2.requestContext)


  "requestContext": {
    "accountId": "offlineContext_accountId",
    "apiId": "offlineContext_apiId",
    "authorizer": {
      "id": "grQA30BuMSYhxUGoU7R9o85z52R2",
      "role": "user",
      "jwt": {
        "claims": {
          "iss": "https://xxxxxxxx.google.com/xxx-app",
          "aud": "xxxx",
          "auth_time": 1645499322,
          "user_id": "xxxxxxx",
          "sub": "xxxxx",
          "iat": 1645499329,
          "exp": 1645502929,
          "phone_number": "xxxxxxx",
          "firebase": {
            "identities": {
              "phone": [
                "xxxxxx"
              ]
            },
            "sign_in_provider": "phone"
          }
        }
      }
    },
    "domainName": "offlineContext_domainName",
    "domainPrefix": "offlineContext_domainPrefix",
    "http": {
      "method": "POST",
      "path": "/users/login",
      "protocol": "HTTP/1.1",
      "sourceIp": "::1",
      "userAgent": "PostmanRuntime/7.29.0"
    },
    "requestId": "offlineContext_resourceId",
    "routeKey": "POST /users/{proxy+}",
    "stage": "$default",
    "time": "22/Feb/2022:09:33:05 +0530",
    "timeEpoch": 1645502585642
  }

Serverless.yml

provider:
  tags:
    project: XFone
  name: aws
  stage: dev
  runtime: nodejs14.x
  region: us-east-2
  logRetentionInDays: 7
  logs:
    httpApi: true
  httpApi:
    metrics: true
    useProviderTags: true
    payload: "2.0"
    cors: true
    authorizers:
      firebaseAuth:
        type: request
        identitySource: $request.header.Authorization
        resultTtlInSeconds: 300
        functionName: firebaseAuth
        payloadVersion: "2.0"
functions:
  firebaseAuth:
    handler: src/auth/authorizeHandler.authorize
  testApi:
    handler: src/test.handler
  api:
    handler: src/app.handler
    events:
      - httpApi:
          method: "OPTIONS"
          path: "/{proxy+}"
      - httpApi:
          method: "GET"
          path: "/users/{proxy+}"
          authorizer:
            name: firebaseAuth
            type: request
pgrzesik commented 3 years ago

Hey @jega-ms - it seems like something specific to serverless-offline plugin so you might need to consult the features that are supported on that plugin side and report potential issues there.

smashercosmo commented 2 years ago

@jega-ms I don't think that simple responses are even supported by serverless-offline. I've just created this issue in serverless-offline repo https://github.com/dherault/serverless-offline/issues/1475

TriangularCube commented 1 year ago

Simple responses are supported now, but this error is still persistent. I've made a new report here.

lepirlouit commented 1 month ago

in typescript, I had to change the event type of the handler from APIGatewayProxyEventBase<YourCustomContextType> to APIGatewayProxyEventV2WithLambdaAuthorizer<YourCustomContextType>