【问题标题】:AWS Lambda C# - Accessing custom contextAWS Lambda C# - 访问自定义上下文
【发布时间】:2017-10-14 21:09:31
【问题描述】:

我有一个用 .NET Core (C#) 编写的简单 Lambda 函数,它使用 APIGatewayProxyRequest 对象遍历所有请求属性。

如果我测试这个 lambda 函数(来自 AWS Lambda),并向它传递一个包含基本信息的示例事件配置:

我可以像这样得到这些信息:

public string FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
        logger.Logger.Log($"Body: {request.Body}  \n");
        logger.Logger.Log($"Path: {request.Path}  \n");
        logger.Logger.Log($"Resource: {request.Resource}  \n");

我如何从相同的数据访问自定义上下文或授权值:

我试过了:

logger.Logger.Log($"RequestContext Authorizor: {request.RequestContext.Authorizer}  \n");

包括它的不同属性(StringKeyPrincipleId 等)

从 Node.js 看来,这可以通过使用这个来简单地实现:

event.requestContext.authorizer.customKey

C#中没有这样的东西吗?

【问题讨论】:

  • 嗯,这很奇怪,是的,所以在 nodeJS 中我只是这样做。 event.requestContext.authorizer - 你确实意识到这是一个小写的“a”对 - 授权人?
  • 是的,我明白这一点,在使用 node.js 时。使用 APIGatewayProxyRequest 对象时,根据命名空间和对象属性,它是大写的。似乎有一种非常不同的方式可以根据所使用的语言访问三个。仍然找不到通过 C# 的方式
  • 你看到了吗:stackoverflow.com/questions/43205120/… - 在这里吐口水,你能把 requestContext 变成一个字符串并记录下来吗?
  • 是的,看到了,并且已经在项目中记录了评论。理想情况下,我不喜欢使用“临时”和自称“肮脏”的方式来获取这些。我不明白为什么你可以轻松地为节点获得这个,但不是。网核 C#
  • 是的,它确实看起来很奇怪,但在 AWS 堆栈上很少有这样的东西,例如,我认为目前 Cognito 身份池中缺少一些东西,我想这些东西即将到来。抱歉,我无法提供更多帮助 - 仅在 Lambda 上使用 JS!

标签: c# amazon-web-services aws-lambda aws-api-gateway


【解决方案1】:

所以,在花了 3 天时间解决这个问题并在 AWS 工程师的帮助下,这就是我发现的;

  • 从 Lambda 函数访问 $context$authorizer 或任何其他 custom variables 存在限制,通过 .Net Core 在 C# 中编写

正在为此为 AWS 团队创建新的服务请求。

解释一下:

目前,在 node.js 中,您可以访问传递给 Lambda 函数(在 event 参数内)的整个数据有效负载,其中包括所有自定义变量(您可以直接访问它 - 对于问题示例,像这样:event.requestContext.authorizer.customKey

这与 C# 等效项不同 - 它在 Lambda 函数中使用 APIGatewayProxyRequest 请求对象。因此,尽管您可以访问节点内的整个有效负载(包括所有自定义变量),但在 C# 中,您只能访问 APIGatewayProxyRequest 对象。可以找到here的属性:

简而言之:

public string Body { get; set; }
public IDictionary<string, string> Headers { get; set; }
public string HttpMethod { get; set; }
public bool IsBase64Encoded { get; set; }
public string Path { get; set; }
public IDictionary<string, string> PathParameters { get; set; }
public IDictionary<string, string> QueryStringParameters { get; set; }
public ProxyRequestContext RequestContext { get; set; }
public string Resource { get; set; }
public IDictionary<string, string> StageVariables { get; set; }

基于对象,这将不允许访问自定义或“未知”属性,即使它们是有效负载的一部分。

长话短说,截至目前:如果您希望使用任何类型的自定义变量,您需要通过 node(event) / python 对其进行编码,或者可能覆盖APIGatewayProxyRequest 中的现有属性对象。

更新:

有一种解决方法可以访问传入数据的整个有效负载:

在此之前的解决方法是让您的 Lambda 函数接收 System.IO.Stream 而不是 APIGatewayProxyRequest。然后您可以访问可以自己解析的原始 JSON。您可以从该 JSON 中获取您需要的信息,然后将 JSON 反序列化为 APIGatewayProxyRequest。

【讨论】:

  • 很高兴知道,它实际上不起作用真是太神奇了!更新做得很好。
  • Java 有同样的问题 :(
【解决方案2】:

我不知道即使在今天(差不多 3 年后 - 我是)人们是否对此感到疑惑,但我已经找到了一种方法。可能会有所帮助。

注意:这仅适用于使用 DotNet SDK 构建的 lambda。

在 AWS API G/W 映射模板中,您需要创建一个与 ApiGatewayProxyRequest class 匹配的 JSON 模板,以便对其进行反序列化。在下面的示例中,我试图从请求中提取正文,并从请求的上下文中提取源 ip 和用户代理。

{
    "Body": "$util.escapeJavaScript($input.body)",
    "RequestContext" : {
    "Identity" : {
        "SourceIp" : "$context.identity.sourceIp",
        "UserAgent" :  "$context.identity.userAgent"
    },
    "RequestId" : "$context.requestId"
}

}

现在,要在 lambda 中访问这些值,您可以执行以下操作:

public async Task<SomeResponse> FunctionHandler(APIGatewayProxyRequest gatewayProxyRequest, ILambdaContext context)
    {
        var requestContext = gatewayProxyRequest.RequestContext;
        var sourceIP = requestContext?.Identity?.SourceIp;
        var body = gatewayProxyRequest.Body;
        .
        .
        .
    }

【讨论】:

    猜你喜欢
    • 2019-04-13
    • 2017-07-15
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 2021-01-09
    • 2018-01-28
    • 1970-01-01
    • 2014-08-09
    相关资源
    最近更新 更多