Skip to content

Bug: APIGatewayHttpResolver doesn't make custome attribute under requestContext.authorizer available in the function #3444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dennisseidel opened this issue Dec 3, 2023 · 11 comments · Fixed by #3454
Assignees
Labels
event_sources Event Source Data Class utility not-a-bug

Comments

@dennisseidel
Copy link

Expected Behaviour

All paramters that are part of the input object unter authorizer are available in the function and accessible on the object.

Current Behaviour

APIGatewayHttpResolver doesn't pass in attribute from requestContext.authorizer. My understanding is that i can in the lambda authorizer can add ther custome attributes e.g. like tenantId but that doesn't get passed to the function. Currently the expected tenantId mis missing:

{"level":"ERROR","location":"initialize:22","message":"event: {'body': '{\"name\": \"test\"}', 'cookies': None, 'decoded_body': '{\"name\": \"test\"}', 'headers': {'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'}, 'http_method': 'POST', 'is_base64_encoded': False, 'json_body': {'name': 'test'}, 'path': '/initialize', 'path_parameters': None, 'query_string_parameters': None, 'raw_event': '[SENSITIVE]', 'raw_path': '/prod/initialize', 'raw_query_string': '', 'request_context': {'account_id': '[Cannot be deserialized]', 'api_id': '[Cannot be deserialized]', 'authentication': None, 'authorizer': {'get_lambda': None, 'iam': None, 'jwt_claim': None, 'jwt_scopes': None, 'raw_event': '[SENSITIVE]'}, 'domain_name': '[Cannot be deserialized]', 'domain_prefix': '[Cannot be deserialized]', 'http': {'method': 'POST', 'path': '/initialize', 'protocol': 'HTTP/1.1', 'raw_event': '[SENSITIVE]', 'source_ip': '127.0.0.1', 'user_agent': 'Custom User Agent String'}, 'raw_event': '[SENSITIVE]', 'request_id': '[Cannot be deserialized]', 'route_key': '[Cannot be deserialized]', 'stage': 'prod', 'time': '[Cannot be deserialized]', 'time_epoch': '[Cannot be deserialized]'}, 'route_key': '$default', 'stage_variables': None, 'version': '2.0'}","timestamp":"2023-12-03 20:48:07,087+0000","service":"service_undefined"}

Code snippet

from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler.exceptions import (
    ServiceError
)
import boto3
import json

app = APIGatewayHttpResolver()
s3_client = boto3.client('s3')
logger = Logger(level="ERROR")


@app.post("/initialize")
def initialize():
    logger.error(f"event: {app.current_event}")
    try:
        body = app.current_event.json_body
        #tenant_id = app.current_event.request_context.authorizer.tenantId
        if not body or 'name' not in body:
            raise ServiceError(502, "Name of file is required.")
        return {
            "message": "File upload initiated successfully.",
        }

    except Exception as e:
        logger.error(f"Error initiating multipart upload: {str(e)}")
        raise ServiceError(502, "Could not create multipart urls.")

def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({
            "event": event,
            "tenantId": event.get("requestContext", {}).get("authorizer", {})
        })
    }
    #return app.resolve(event, context)

requreiments.txt

aws-lambda-powertools[tracer]  # Tracer requires AWS X-Ray SDK dependency
boto3

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Sample SAM Template for powertools-quickstart
Globals:
    Function:
        Timeout: 10
        Environment:
            Variables:
                POWERTOOLS_LOG_LEVEL: DEBUG
Resources:
    UploaderFunction:
        Type: AWS::Serverless::Function
        Properties:
            CodeUri: hello_world/
            Handler: app.lambda_handler
            Runtime: python3.12
            Architectures:
                - x86_64
            Events:
                Initialize:
                    Type: HttpApi
                    Properties:
                        Path: /initialize
                        Method: post
Outputs:
    UploaderApi:
        Description: "API Gateway endpoint URL for Prod stage for Hello World function"
        Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"

 sam local invoke "UploaderFunction" -e ./events/initalize-event.json

initalize-event.json

{
  "version": "2.0",
  "routeKey": "$default",
  "rawPath": "/prod/initialize",
  "rawQueryString": "",
  "headers": {
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
  },
  "requestContext": {
    "http": {
      "method": "POST",
      "path": "/initialize",
      "protocol": "HTTP/1.1",
      "sourceIp": "127.0.0.1",
      "userAgent": "Custom User Agent String"
    },
    "authorizer": {
      "tenantId": "tenantA"
    },
    "stage": "prod"
  },
  "body": "{\"name\": \"test\"}",
  "isBase64Encoded": false
}


### Possible Solution

_No response_

### Steps to Reproduce

- add the code snippets to the template crated with `sam init --runtime python3.12 --dependency-manager pip --app-template hello-world --name powertools-quickstart`
- execute ` sam local invoke "UploaderFunction" -e ./events/initalize-event.json` (see above) 
- see the log output that within the function the object doesn't contain the custome `tenantId` field on the `requestContext.authorizer` anymore.

### Powertools for AWS Lambda (Python) version

latest

### AWS Lambda function runtime

3.11

### Packaging format used

Lambda Layers

### Debugging logs

_No response_
@dennisseidel dennisseidel added bug Something isn't working triage Pending triage from maintainers labels Dec 3, 2023
Copy link

boring-cyborg bot commented Dec 3, 2023

Thanks for opening your first issue here! We'll come back to you as soon as we can.
In the meantime, check out the #python channel on our Powertools for AWS Lambda Discord: Invite link

@dennisseidel dennisseidel changed the title Bug: APIGatewayHttpResolver doesn't make attribute under requestContext.authorizer available Bug: APIGatewayHttpResolver doesn't make custome attribute under requestContext.authorizer available in the function Dec 3, 2023
@dennisseidel
Copy link
Author

dennisseidel commented Dec 3, 2023

An example project might make it easier :) https://github.com/dennisseidel/aws-powertool-bug-example

Thank you for your great work!

@heitorlessa
Copy link
Contributor

ACK; seeing shortly (pulling my laptop at the airport gate)

@heitorlessa
Copy link
Contributor

@dennisseidel ah that's not a bug (phew!). You'd have to use .get to access the key you inject from the authorizer. Since you can have arbitrary key and value types passed down by the Lambda Authorizer to your Lambda Integration, we wrap as a dictionary so you have full control (we wouldn't know otherwise).

Here's the updated line that causes an error

app.current_event.request_context.authorizer.get("tenantId")

# Instead of .<attribute> which would lead to an AttributeError
# app.current_event.request_context.authorizer.tenantId

Does that make sense?

That said, looking at the implementation we have an incorrect property get_lambda that shouldn't be there but we can remove it this coming week to avoid confusion :)


API Reference

@heitorlessa
Copy link
Contributor

An example project might make it easier :) dennisseidel/aws-powertool-bug-example

Thank you for your great work!

this was so helpful, spot the issue in 10s, needed more time to confirm docs and test locally

@heitorlessa heitorlessa added event_sources Event Source Data Class utility and removed bug Something isn't working triage Pending triage from maintainers labels Dec 3, 2023
@heitorlessa heitorlessa moved this from Triage to Backlog in Powertools for AWS Lambda (Python) Dec 3, 2023
@heitorlessa heitorlessa self-assigned this Dec 3, 2023
@dennisseidel
Copy link
Author

@heitorlessa Thank you for the quick support 🙏 Indeed I no bug but just me not using it right 🙈

@github-project-automation github-project-automation bot moved this from Backlog to Coming soon in Powertools for AWS Lambda (Python) Dec 4, 2023
Copy link
Contributor

github-actions bot commented Dec 4, 2023

⚠️COMMENT VISIBILITY WARNING⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.

@heitorlessa
Copy link
Contributor

reopening as @leandrodamascena is testing and lambda key is injected in HTTP API, meaning .get() might not work as the authorization context is wrapped under the lambda key... hence why we had get_lambda, despite UX not being explicit enough.

we'll come back with a solution

@heitorlessa
Copy link
Contributor

@dennisseidel we improved the experience thanks to you! Today's release will have a new get_context() to make it less ambiguous for both API Gateway REST (v1) and HTTP API (v2).

from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools import Logger

app = APIGatewayRestResolver()
logger = Logger(level="INFO")


@app.get("/")
def initialize():
    context: dict = app.current_event.request_context.authorizer.get_context()
    logger.info(context.get("tenantId"))

def lambda_handler(event, context):
    return app.resolve(event, context)

@github-project-automation github-project-automation bot moved this from Pending review to Coming soon in Powertools for AWS Lambda (Python) Dec 6, 2023
Copy link
Contributor

github-actions bot commented Dec 6, 2023

⚠️COMMENT VISIBILITY WARNING⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.

@heitorlessa heitorlessa added the pending-release Fix or implementation already in dev waiting to be released label Dec 6, 2023
Copy link
Contributor

github-actions bot commented Dec 6, 2023

This is now released under 2.29.0 version!

@github-actions github-actions bot removed the pending-release Fix or implementation already in dev waiting to be released label Dec 6, 2023
@heitorlessa heitorlessa moved this from Coming soon to Shipped in Powertools for AWS Lambda (Python) Dec 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
event_sources Event Source Data Class utility not-a-bug
Projects
Status: Shipped
3 participants