In APIGatewayProxyFunction.FunctionHandlerAsync
where the requestStream
gets deserialised into APIGatewayProxyRequest
we lose all custom claims that were present in the requestStream
's json.
It'd be nice if apiGatewayRequest.RequestContext.Authorizer
would contain a Dictionary<string,string>
with claims which get added to HttpContext.User
.
Thanks,
Lars
Any updates on this, I have just experienced the same limitation. Having the apiGatewayRequest.RequestContext.Authorizer as a dictionary would be a great solution.
@ShaneGMamet,
As a workaround until there's an official solution, I've written this https://www.nuget.org/packages/MhLabs.Lambda.ApiGatewayAuthorizer/1.0.1
https://github.com/mhlabs/MhLabs.Lambda.ApiGatewayAuthorizer
Also running into this. Would love a fix!
I am also hitting this issue, Any idea on when a fix might become available?
If somebody could send me a sample request that would speed up my time to getting this implemented. To send a sample request add the environment variable LAMBDA_NET_SERIALIZER_DEBUG
with a value of true
. Then after executing the request where the claims are stripped go to your CloudWatch logs and grab the JSON request string.
Hi I added this but it didnt give me much info,
you can get the raw request by taking the input as a Stream
public APIGatewayProxyResponse ProxyFunctionHandler(System.IO.Stream input, ILambdaContext context) {
StreamReader reader = new StreamReader(input);
string request = reader.ReadToEnd();
Console.WriteLine(request);
return new APIGatewayProxyResponse { StatusCode = 200 };
}
The full request is quite big but the data that is missing looks like this.
{
"requestContext": {
"authorizer": {
"claims": {
"sub": "XXXX",
"aud": "XXXX",
"token_use": "id",
"auth_time": "1503560181",
"iss": "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_XXXXXX",
"cognito:username": "TestUser",
"exp": "Thu Aug 24 08:36:21 UTC 2017",
"iat": "Thu Aug 24 07:36:21 UTC 2017"
}
}
}
}
It is possible to deserialize the object to the classes below using JsonConvert as a work around
var claimsFix = JsonConvert.DeserializeObject<ClaimsFix>(request);
class ClaimsFix
{
public RequestContext RequestContext;
}
public class RequestContext
{
public Authorizer Authorizer;
}
public class Authorizer
{
public Dictionary<string, string> Claims { get; set; }
}
As part of the .NET Core 2.0 Lambda release today I updated Amazon.Lambda.APIGatewayEvents
and Amazon.Lambda.AspNetCoreServer
to pass along the claims and create the HttpContext.User similar to how @ljacobsson was doing in his code.
I'm going to close this as I believe that solves the problem. Feel free to reopen or open a new issue if there are more use cases that are not met.
@normj Thanks for this.
I think it is a great addition that we can now use APIGatewayCustomAuthorizerContext
as a dictionary, however, I'm not sure how I should go about this when returning an APIGatewayCustomAuthorizerResponse
in my custom authorizer?
In particular, when doing a custom authorizer, we can return an APIGatewayCustomAuthorizerResponse
with the Context
property being of type: APIGatewayCustomAuthorizerContextOutput
.
However, looking at APIGatewayCustomAuthorizerContextOutput
, it is still using:
public string StringKey { get; set; }
public int? NumKey { get; set; }
public bool? BoolKey { get; set; }
... which are now marked obsolete in APIGatewayCustomAuthorizerContext
.
I guess the APIGatewayCustomAuthorizerContextOutput
should derive from Dictionary<string, object>
as well, in order to make it compatible with the new APIGatewayCustomAuthorizerContext
? ( and likewise, mark the StringKey
, Numkey
, and BoolKey
attributes as obsolete? )
@swlasse I believe your issue is covered by this github issue https://github.com/aws/aws-lambda-dotnet/issues/159 which I still need to look into.
@normj, yeah, that looks right. At the moment we serialize our custom context into the StringKey
parameter of the APIGatewayCustomAuthorizerContextOutput
. It works, but its not ideal.
It could be nice though if we could send through Claims and see them getting picked up by the new Claims
property on APIGatewayCustomAuthorizerContext
.
With #159 resolved, we can now add a key-val pair to APIGatewayCustomAuthorizerContextOutput
holding our own custom context serialized as a JSON string. Strictly speaking, we could do that before with the StringKey
property, but the property name was a bit confusing. With APIGatewayCustomAuthorizerContextOutput
now deriving from Dictionary<string, object>
we can set our own key, and name it as we like. This gives us the flexibility we need in order to send trough claims, etc. Thanks for resolving this.
Hi, I am a new bee to API Gateway and Lambda. I am trying to get the authorized user from my custom authorizer that returns user object. After enabling APIGatewayProxyRequest logging (LAMBDA_NET_SERIALIZER_DEBUG) I can see my user object getting logged in cloudwatch but when I am serializing the request in my lambda the authorizer section is empty.
Lambda Deserialize Amazon.Lambda.APIGatewayEvents.APIGatewayProxyRequest:
"requestContext": {
"authorizer": {
"principalId": "**",
"user": "
},
"resourcePath": "/{proxy+}",
"httpMethod": "GET" .....
}
}
My Lambda: "Authorizer": {}
I highly appreciate your help.
Thank you.
@normj : I think I'm missing something. I have a CustomAuthorizer returning a valid policy (taken from the blueprint). I want my underlying Lambda service to be able to access the PrincipalId, ideally in the HttpContext.User object. It looks as if this is only set when Claims are present in the request? I'm missing how to add Claims in my custom Authorizer? I'm returning a policy statement that looks like this:
PrincipalId: "id-i-want-to-get"
Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": "arn:aws:execute-api:us-east-1:xxxxx:/qa//*"
}
]
}
It looks like I can get the ID by override the PostCreateContext function myself, though it feels like I shouldn't need to do that? Am I missing something? Thanks!
@normj : I have a rather connected question, and decided not to open another thread. What you've done with the APIGatewayProxyRequest is great, but do you have any plans for APIGatewayCustomAuthorizerContextOutput and more specific - allowing the values to be something more than a string value. In general the class is a Dictionary
Most helpful comment
As part of the .NET Core 2.0 Lambda release today I updated
Amazon.Lambda.APIGatewayEvents
andAmazon.Lambda.AspNetCoreServer
to pass along the claims and create the HttpContext.User similar to how @ljacobsson was doing in his code.I'm going to close this as I believe that solves the problem. Feel free to reopen or open a new issue if there are more use cases that are not met.