I am rewriting an ASP.NET Core application from being ran on lambda to run on an ECS Container. Lambda supports the claims injected from Cognito Authorizer out of the box, but Kestrel doesn't.
API requests are coming in through API Gateway, where a Cognito User Pool authorizer is validating the OAuth2 tokens and enriching the claims from the token to the httpContext.
Originally the app was running on lambda where the entry point was inheriting Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
, which extracts those claims and adds them to Request.HttpContext.User.Claims
.
Kestrel of course doesn't support that and AWS ASPNET Cognito Identity Provider seems to be meant for performing the same things that the authorizer is doing.
So I got the idea that maybe I can add some custom code to extract it. The HTTP request injected into lambda looks like this, so I expect it should be the same when it's proxied into ECS
{
"resource": "/{proxy+}",
"path": "/api/authtest",
"httpMethod": "GET",
"headers": {
<...>
},
"queryStringParameters": null,
"pathParameters": {
"proxy": "api/authtest"
},
"requestContext": {
"resourceId": "8gffya",
"authorizer": {
"cognito:groups": "Admin",
"phone_number_verified": "true",
"cognito:username": "normj",
"aud": "3mushfc8sgm8uoacvif5vhkt49",
"event_id": "75760f58-f984-11e7-8d4a-2389efc50d68",
"token_use": "id",
"auth_time": "1515973296",
"you_are_special": "true"
}
<...>
}
Is it possible, and how could I go about it to add all the key / value pairs from requestContext.authorizer
to Request.HttpContext.User.Claims
?
I found a different solution for this.
Instead of trying to modify the HttpContext
I map the authorizer output to request headers in the API Gateway integration. Downside of this is that each claim needs to be hardcoded as it doesn't seem to be possible to iterate over them.
Example terraform
resource "aws_api_gateway_integration" "integration" {
rest_api_id = "${var.aws_apigateway-id}"
resource_id = "${aws_api_gateway_resource.proxyresource.id}"
http_method = "${aws_api_gateway_method.method.http_method}"
integration_http_method = "ANY"
type = "HTTP_PROXY"
uri = "http://${aws_lb.nlb.dns_name}/{proxy}"
connection_type = "VPC_LINK"
connection_id = "${aws_api_gateway_vpc_link.is_vpc_link.id}"
request_parameters = {
"integration.request.path.proxy" = "method.request.path.proxy"
"integration.request.header.Authorizer-ResourceId" = "context.authorizer.resourceId"
"integration.request.header.Authorizer-ResourceName" = "context.authorizer.resourceName"
"integration.request.header.Authorizer-Scopes" = "context.authorizer.scopes"
"integration.request.header.Authorizer-TokenType" = "context.authorizer.tokenType"
}
}