Having worked extensively with Node.js in the past, we are currently investigating ASP.NET Core as an alternative Lambda platform.
In the past, our API Gateway-fronted services relied on a custom authorizer, which authenticated the user and retrieved a list of resource-based permission policies from our company's IAM service. The authorizer attaches that list to the authContext key. Our services would integrate with API Gateway via Lambda Proxy and extract the principal object from the raw proxy request.
When using Amazon.Lambda.AspNetCoreServer to translate between API Gateway and ASP.NET, we are unable to arrive at a similar scenario.
Amazon.Lambda.AspNetCoreServer::ApiGatewayProxyFunction::FunctionHandlerAsync(Stream responseStream, ILambdaContext lambdaContext), or any equivalent Lambda handler signature for that matter, receives the complete, raw request in the first parameter. It is possible to serialize the stream (for example, into a JSON.NET JObject) and extract the principal object there.
However, what proves difficult is accessing that data within the ASP.NET application. I am not convinced that the authorizer response is passed to the HTTP context. When checking it, the ClaimsPrincipal context.User key contains no data.
Several solutions were thrown around:
Is there a way to achieve this cleanly?
We've in the exact same situation and I can by no means offer a nice and clean solution, but I have a workaround.
If you look at the request payload, the json is formatted like this:
{
[...]
"requestContext": {
[...]
"authorizer": {
"claims": {
"claim1": "value1",
"claim2": "value2",
"claim3": "value3",
}
},
[...]
In APIGatewayProxyFunction.FunctionHandlerAsync
they deserialize the requestStream
into an APIGatewayProxyRequest
. If you step into that class you'll find that the Authorizer part of the json gets deserialized into:
public class APIGatewayCustomAuthorizerContext
{
public string PrincipalId { get; set; }
public string StringKey { get; set; }
public int? NumKey { get; set; }
public bool? BoolKey { get; set; }
}
I.e all claims are lost in deserialization. I've posted this issue here: https://github.com/aws/aws-lambda-dotnet/issues/98
Now to the workaround, I've just put something that "works" together here (Code here):
Note that it's very untested. :-)
Usage:
public class LambdaEntryPoint : APIGatewayAuthorizerProxyFunction
{
protected override void Init(IWebHostBuilder builder)
{
builder
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseApiGateway();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With