From 3d86eff3929a847d3ac2f2b11b43c69245a241a1 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Wed, 22 Jan 2025 10:07:21 +0000 Subject: [PATCH 1/2] Adding example on how to work with optional security routes --- docs/core/event_handler/api_gateway.md | 8 ++++ .../security_schemes_global_and_optional.py | 48 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 examples/event_handler_rest/src/security_schemes_global_and_optional.py diff --git a/docs/core/event_handler/api_gateway.md b/docs/core/event_handler/api_gateway.md index 39554c21e40..07d82fa1e84 100644 --- a/docs/core/event_handler/api_gateway.md +++ b/docs/core/event_handler/api_gateway.md @@ -1103,6 +1103,14 @@ Security schemes are declared at the top-level first. You can reference them glo 1. Using the oauth security scheme defined bellow, scoped to the "admin" role. +=== "Global security schemes and optional security per route" + + ```python title="security_schemes_global_and_optional.py" hl_lines="20 35-44" + --8<-- "examples/event_handler_rest/src/security_schemes_global_and_optional.py" + ``` + + 1. To make security optional in a specific route, an empty security requirement ({}) can be included in the array. + OpenAPI 3 lets you describe APIs protected using the following security schemes: | Security Scheme | Type | Description | diff --git a/examples/event_handler_rest/src/security_schemes_global_and_optional.py b/examples/event_handler_rest/src/security_schemes_global_and_optional.py new file mode 100644 index 00000000000..565f72eed4d --- /dev/null +++ b/examples/event_handler_rest/src/security_schemes_global_and_optional.py @@ -0,0 +1,48 @@ +from aws_lambda_powertools import Logger, Tracer +from aws_lambda_powertools.event_handler import ( + APIGatewayRestResolver, +) +from aws_lambda_powertools.event_handler.openapi.models import ( + OAuth2, + OAuthFlowAuthorizationCode, + OAuthFlows, +) + +tracer = Tracer() +logger = Logger() + +app = APIGatewayRestResolver(enable_validation=True) + + +@app.get("/protected", security=[{"oauth": ["admin"]}]) # (1)! +def protected() -> dict: + return {"hello": "world"} + + +@app.get("/unprotected", security=[{}]) # (1)! +def unprotected() -> dict: + return {"hello": "world"} + + +@logger.inject_lambda_context +@tracer.capture_lambda_handler +def lambda_handler(event, context): + return app.resolve(event, context) + + +if __name__ == "__main__": + print( + app.get_openapi_json_schema( + title="My API", + security_schemes={ + "oauth": OAuth2( + flows=OAuthFlows( + authorizationCode=OAuthFlowAuthorizationCode( + authorizationUrl="https://xxx.amazoncognito.com/oauth2/authorize", + tokenUrl="https://xxx.amazoncognito.com/oauth2/token", + ), + ), + ), + }, + ), + ) From 2961d7c031070427c6011ae6e1c73b5d2f62ec57 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Wed, 22 Jan 2025 11:22:11 +0000 Subject: [PATCH 2/2] Adding example on how to work with optional security routes --- docs/core/event_handler/api_gateway.md | 2 +- .../src/security_schemes_global_and_optional.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/event_handler/api_gateway.md b/docs/core/event_handler/api_gateway.md index 07d82fa1e84..1f9618839f9 100644 --- a/docs/core/event_handler/api_gateway.md +++ b/docs/core/event_handler/api_gateway.md @@ -1105,7 +1105,7 @@ Security schemes are declared at the top-level first. You can reference them glo === "Global security schemes and optional security per route" - ```python title="security_schemes_global_and_optional.py" hl_lines="20 35-44" + ```python title="security_schemes_global_and_optional.py" hl_lines="22 37-46" --8<-- "examples/event_handler_rest/src/security_schemes_global_and_optional.py" ``` diff --git a/examples/event_handler_rest/src/security_schemes_global_and_optional.py b/examples/event_handler_rest/src/security_schemes_global_and_optional.py index 565f72eed4d..2a890efd5e4 100644 --- a/examples/event_handler_rest/src/security_schemes_global_and_optional.py +++ b/examples/event_handler_rest/src/security_schemes_global_and_optional.py @@ -14,7 +14,7 @@ app = APIGatewayRestResolver(enable_validation=True) -@app.get("/protected", security=[{"oauth": ["admin"]}]) # (1)! +@app.get("/protected", security=[{"oauth": ["admin"]}]) def protected() -> dict: return {"hello": "world"}