Miserlou / Zappa

Serverless Python
https://blog.zappa.io/
MIT License
11.89k stars 1.2k forks source link

Context header mappings do not override http headers #1585

Open bharling opened 6 years ago

bharling commented 6 years ago

Context

I'm using an external lambda authorizer on APIGateway and returning some user info in the context that will be consumed by my api. I'm using the context_header_mappings setting to pass the user_id from the gateway authorizer to the api in the apigw_user_id header. The APIGW authorizer function is more used just for authentication and could potentially return None as the value for apigw_user_id and it would be up to the view to decide whether an authenticated user is required. However, if I deliberately make a request with an unauthtenticated user, but manually supply a apigw_user_id header, that header is passed straight to my function essentially bypassing the authorizer.

Expected Behavior

Headers defined in context_header_mappings should always override manually passed headers if the Authorizer supplies a value for them ( even if the value is None )

Actual Behavior

If an Authorizer returns None for a context variable, then the value from any HTTP header matching that name is used instead.

Possible Fix

Alter function here: https://github.com/Miserlou/Zappa/blob/6ab48b0db4ce1679935a36a63d44b4fca183632b/zappa/wsgi.py#L46 to favour values passed from the APIGW Authorizer context over any value passed in the original header.

Steps to Reproduce

  1. Create an external lambda authorizer function returning the authenticated user id ( or None ) in a context variable
  2. Attach the authorizer to a zappa deployed function
  3. Include context_header_mappings in zappa_settings.json mapping the apigw context variable to an HTTP header
  4. Make a curl request to the deployed api, omitting any Authorization tokens required by the gateway, but include the header mapped from the context variable
  5. The mapped header is passed directly to the function, overriding whatever the gateway has returned

Your Environment

{
    "dev": {
        "app_function": "app.app",
        "aws_region": "eu-central-1",
        "profile_name": "default",
        "project_name": "crowdcomms-livepolling",
        "runtime": "python3.6",
        "s3_bucket": "zappa-dwtdfjpuq",
        "context_header_mappings": {
          "apigw_user_id": "authorizer.user_id",
          "authorization": "authorizer.auth_token"
        }
    }
}
bharling commented 6 years ago

Note - I'm just using zappa to package my function and manually deploying to an existing gateway with the authorizer function attached using the AWS console.