I have a Quarkus (3.12.3
) AWS lambda application deployed as a Java 21 zip package (for SnapStart, which doesn’t support containers as of writing). I’m using AWS HTTP v2 API gateway (payload format version 2.0
) with a Cognito authorizer. All routes are currently set to be authorized by an admin role, which I understood to map from a Cognito group.
I’m using quarkus-hibernate-orm-rest-data-panache
which I understood to not be reactive.
When deploying the application (lambda handler is io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
) it seems the API authentication is successful (Bearer
token in the authorization
header) because Cognito is allowing the request through to the lambda.
However, the response is always 401
. Setting QUARKUS_LOG_LEVEL
to DEBUG
shows the following entry in CloudWatch logs:
DEBUG [io.qua.ver.htt.run.sec.HttpAuthenticator] (vert.x-eventloop-thread-0) Authentication has not been done, returning HTTP status 401
My questions are: why is the application returning a 401? Do I need to be handling the JWT from Cognito? I wasn’t expecting vert.x to be involved, is there another dependency that is causing this? Is this an expected part of the request/response lifecycle?
My reading of the AWS Lambda Quarkus docs, specifically the following phrase is that I shouldn’t need any more configuration:
When you invoke an HTTP request on the API Gateway, the Gateway turns that HTTP request into a JSON event document that is forwarded to a Quarkus Lambda. The Quarkus Lambda parses this json and converts in into an internal representation of an HTTP request that can be consumed by any HTTP framework Quarkus supports (Jakarta REST, servlet, Reactive Routes).
The build.gradle
(test excluded):
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
// Deployment as an AWS Lambda behind an AWS HTTP v2 API Gateway
// Breaks the dev UI, see https://github.com/quarkusio/quarkus/issues/23014
implementation 'io.quarkus:quarkus-amazon-lambda-http'
// JSON request and response handling
implementation 'io.quarkus:quarkus-rest-jackson'
// OpenAPI Swagger Docs
implementation 'io.quarkus:quarkus-smallrye-openapi'
// Database entity mapping and rest json mapping
implementation 'io.quarkus:quarkus-hibernate-orm-rest-data-panache'
// Entity validation
implementation 'io.quarkus:quarkus-hibernate-validator'
// Database connection
implementation 'io.quarkus:quarkus-jdbc-postgresql'
implementation 'io.quarkus:quarkus-agroal'
implementation 'software.amazon.jdbc:aws-advanced-jdbc-wrapper:2.3.7'
// Database entity versioning and auditing
implementation 'io.quarkus:quarkus-hibernate-envers'
// Dependency Injection
implementation 'io.quarkus:quarkus-arc'
// Security
implementation 'io.quarkus:quarkus-security'
// AWS SDKs
implementation(platform("software.amazon.awssdk:bom:2.26.9"))
implementation 'software.amazon.awssdk:rds'
}
The application.properties
file:
# Core
quarkus.analytics.disabled=true
quarkus.http.host=0.0.0.0
quarkus.http.root-path=/default/v1/
quarkus.http.non-application-root-path=/q/
quarkus.hibernate-orm.database.generation=none
# Security
quarkus.security.jaxrs.default-roles-allowed=admin
# Custom Credential provider
#
# AWS RDS IAM authentication tokens are only valid for 15 mins
# https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html
quarkus.datasource.db-kind=postgresql
quarkus.datasource.jdbc.driver=software.amazon.jdbc.Driver
quarkus.datasource.jdbc.url=jdbc:aws-wrapper:postgresql://127.0.0.1:5678/app?user=abc&password=abc
# AWS Lambda
quarkus.snapstart.enable=true
# AWS Lambda Cognito JWT group mapping to Quarkus roles
# https://quarkus.io/guides/aws-lambda-http#security-integration
quarkus.lambda-http.enable-security=true
Some additional notes:
- Am using the AWS Advanced JDBC Wrapper to connect to a PostgreSQL RDS instance with RDS IAM Credentials.