I have created a http lambda with a custom security provider. But the custom security provider does not work as expected. The same works fine as @QuarkusTest
. But when I deploy the code to AWS (using sam deploy), it doesn't work. I simply get a NullpointerException
in my GreetingResource
because the security context is null.
The security context is null because the flow doesn't go through my custom security provider - MBizSecurityProvider
(which is not the case when running the test case). In AWS console -> API Gateway -> Authorization, I see
No authorizer attached to $default
Normally I expect an authorizer to be shown in the AWS console. I am using the quarkus generated sam.jvm.yaml/sam.native.yaml
and sam CLI to deploy my artifacts to AWS. I don't see any authorizers mentioned in the generated sam config files neither.
Is there any additional configuration to make it work in AWS. In SAM local it works when setting QUARKUS_AWS_LAMBDA_FORCE_USER_NAME environment variable.
Here is my complete source code
My HTTP Api resource class
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello(@Context SecurityContext securityContext) {
return "hello " + securityContext.getUserPrincipal().getName();
}
}
And my security provider is
@ApplicationScoped
public class MBizSecurityProvider implements LambdaIdentityProvider {
@Override
public SecurityIdentity authenticate(APIGatewayV2HTTPEvent event) {
if (event.getHeaders() == null || !event.getHeaders().containsKey("x-user")) {
throw new RuntimeException("No auth header");
}
if(!event.getHeaders().get("x-user").equalsIgnoreCase("test")) {
throw new RuntimeException("Invalid user");
}
Principal principal = new QuarkusPrincipal(event.getHeaders().get("x-user"));
QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder();
builder.setPrincipal(principal);
return builder.build();
}
}
I have enabled security in in application.properties with property quarkus.lambda-http.enable-security=true
This is my test case that works fine.
@QuarkusTest
public class GreetingTest {
@Test
public void test() {
APIGatewayV2HTTPEvent request = request("/hello");
request.setHeaders(ImmutableMap.of("x-user", "test"));
request.getRequestContext().setAuthorizer(new APIGatewayV2HTTPEvent.RequestContext.Authorizer());
given()
.contentType("application/json")
.accept("application/json")
.body(request)
.when()
.post(AmazonLambdaApi.API_BASE_PATH_TEST)
.then()
.statusCode(200)
.body("body", equalTo("hello test"));
}
private APIGatewayV2HTTPEvent request(String path) {
APIGatewayV2HTTPEvent request = new APIGatewayV2HTTPEvent();
request.setRawPath(path);
request.setRequestContext(new APIGatewayV2HTTPEvent.RequestContext());
request.getRequestContext().setHttp(new APIGatewayV2HTTPEvent.RequestContext.Http());
request.getRequestContext().getHttp().setMethod("GET");
return request;
}
}
It works fine with quarkus-amazon-lambda-rest. Seems to be a bug in quarkus-amazon-lambda-http. Follow this issue for updates github.com/quarkusio/quarkus/issues/24609