aws-lambda-dotnet
aws-lambda-dotnet copied to clipboard
HttpContext is null for AWS Lambda Function Handler (Executable assembly)
Describe the bug
HttpContext is always null after it has been injected into AWS Lambda Function Handler. For comparison, it is populated while using the MinimalAPI approach.
Expected Behavior
HttpContext is populated with Items (and Session data when AWS DynamoDB session provider is used)
Current Behavior
HttpContext object is always null when injected in the AWS Lambda Function Handler.
Reproduction Steps
Code sample illustrating the absence of HttpContext.
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using Amazon.Lambda.RuntimeSupport;
using Amazon.Lambda.Serialization.SystemTextJson;
using Microsoft.AspNetCore.DataProtection;
var authorizerSettings = new SessionAuthorizerSettings();
var serviceCollection = new ServiceCollection();
serviceCollection.AddAWSLambdaHosting(LambdaEventSource.HttpApi);
serviceCollection.AddSingleton<ISessionAuthorizerSettings, SessionAuthorizerSettings>();
serviceCollection
.AddDataProtection()
.SetApplicationName(authorizerSettings.DataProtectionAppName)
.DisableAutomaticKeyGeneration();
serviceCollection
.AddHttpContextAccessor();
serviceCollection
.AddAWSDynamoDBDistributedCache(options =>
{
options.TableName = authorizerSettings.CacheTableName;
options.PartitionKeyName = authorizerSettings.PartitionKeyName;
options.TTLAttributeName = authorizerSettings.TTLAttributeName;
})
.AddSession(options =>
{
options.Cookie.Name = ".Cookie.Session";
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
var serviceProvider = serviceCollection.BuildServiceProvider();
var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();
var httpContext = httpContextAccessor?.HttpContext;
var handler = (APIGatewayHttpApiV2ProxyRequest request, ILambdaContext lambdaContext) =>
{
var userId = "12345";
// ISSUE: 'httpContext' is always null and therefore, the session can not be accessed.
var session = httpContext.Session;
var sessionData = ObjectSerializer.Deserialize<SessionPermissions>(session.GetString(userId));
// An example of a typical response from the authorizer to invoke the requested Lambda.
var response = new APIGatewayCustomAuthorizerResponse
{
PolicyDocument = new APIGatewayCustomAuthorizerPolicy
{
Version = "2012-10-17",
Statement = new List<APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement>
{
new()
{
Action = new HashSet<string> {"execute-api:Invoke"},
Effect = "Allow",
Resource = new HashSet<string> { $"arn:aws:execute-api:{lambdaContext.InvokedFunctionArn}:{request.RequestContext.AccountId}:{request.RequestContext.ApiId}/$default/*" }
}
},
},
PrincipalID = userId,
Context = new APIGatewayCustomAuthorizerContextOutput
{
["data"] = sessionData.Data
}
};
};
await LambdaBootstrapBuilder.Create(handler, new DefaultLambdaJsonSerializer())
.Build()
.RunAsync();
Possible Solution
No response
Additional Information/Context
Alternatively, a Minimal API approach was trialed where HttpContext was populated with Items and Session data, however, it returned a response that is incorrect for a Custom Authorizer (Raised in a separate issue)
Context HttpContext is required to access session data.
For this purpose, AWS DynamoDB session provider has been integrated and API Gateway HTTP Payload v2.0 was used.
Apart from the use of Function Handler, the Lambda Entry Point approach was used. This approach faces the same issue as the Function Handler, where HttpContext is null. Amazon.Lambda.AspNetCoreServer
AWS .NET SDK and/or Package version used
- Amazon.Lambda.AspNetCoreServer.Hosting, Version="1.6.1"
- AWS.AspNetCore.DistributedCacheProvider, Version="0.9.2"
- AWSSDK.S3, Version="3.7.103.37"
Targeted .NET Platform
.Net 6
Operating System and version
AWS Lambda