如何在Azure函数C中获取客户端IP地址?

如何在Azure函数C中获取客户端IP地址?,azure,azure-functions,Azure,Azure Functions,我正在使用Azure函数用C编写一个函数,需要获取调用该函数的客户端的ip地址,这可能吗?以下是基于该函数的答案 你应该使用这些函数 如果调试预编译的本地函数,则request.Properties[MS_HttpContext]不可用 request.Properties[RemoteEndpointMessageProperty.Name]在azure上不可用 private string GetClientIp(HttpRequestMessage request) { if (r

我正在使用Azure函数用C编写一个函数,需要获取调用该函数的客户端的ip地址,这可能吗?

以下是基于该函数的答案


你应该使用这些函数

如果调试预编译的本地函数,则request.Properties[MS_HttpContext]不可用 request.Properties[RemoteEndpointMessageProperty.Name]在azure上不可用

private string GetClientIp(HttpRequestMessage request)
{
    if (request.Properties.ContainsKey("MS_HttpContext"))
    {
        return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
    }

    if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
    {
        RemoteEndpointMessageProperty prop;
        prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
        return prop.Address;
    }

    return null;
}
2018年8月21日更新: 现在Azure函数在LoadBalancer之后->我们必须检查请求头以确定正确的客户端IP

private static string GetIpFromRequestHeaders(HttpRequestMessage request)
    {
        IEnumerable<string> values;
        if (request.Headers.TryGetValues("X-Forwarded-For", out values))
        {
            return values.FirstOrDefault().Split(new char[] { ',' }).FirstOrDefault().Split(new char[] { ':' }).FirstOrDefault();
        }

        return "";
    }
既然Azure函数获得了一个HttpRequest参数,并且它们位于负载平衡器的后面,那么这个获取IP地址的函数对我来说很有用:

private static string GetIpFromRequestHeaders(HttpRequest request)
{
      return (request.Headers["X-Forwarded-For"].FirstOrDefault() ?? "").Split(new char[] { ':' }).FirstOrDefault();
}
更新日期:2019年10月18日:

我尝试的解决方案更简单、更快,下面将逐步介绍。但还有一些更为冗长/棘手的备选方案:

登录Azure门户。 登录并拨号时在同一浏览器中打开新选项卡“” 这是Azure后端服务门户,所以在进行更改时稍微小心一点就好了。 从左侧面板展开“订阅”部分,并展开app insight资源所在的Azure订阅。 展开“资源组”部分并展开app insights资源所在的资源组。 展开“提供程序”部分,找到Microsoft.Insights提供程序并展开它。 展开“组件”部分,按名称查找并选择App Insight实例。 在右上方,将模式从只读更改为读写。 单击RESTAPI调用上的编辑按钮。 将新的“DisableIpMasking:true属性”添加到属性部分。 按PUT按钮应用更改。 现在,您的App Insight已启用,可以开始收集客户端IP地址。 对函数执行一些查询。 大约5到10分钟后刷新并测试App Insights数据。
下面是一个扩展方法,它基于我在.Netcore 3.1中看到的内容

public static IPAddress GetClientIpn(this HttpRequest request)
{
    IPAddress result = null;
    if (request.Headers.TryGetValue("X-Forwarded-For", out StringValues values))
    {
        var ipn = values.FirstOrDefault().Split(new char[] { ',' }).FirstOrDefault().Split(new char[] { ':' }).FirstOrDefault();
        IPAddress.TryParse(ipn, out result);
    }
    if (result == null)
    {
        result = request.HttpContext.Connection.RemoteIpAddress;
    }
    return result;
}

正如其他人已经提到的,查看MS_HttpContext的旧方法不再有效。此外,虽然查看X-Forwarded-for的头的方法确实有效,但它只有在Azure中发布后才有效-当您在本地运行时它不会返回值。如果您更喜欢在本地测试以最小化任何pote,这可能很重要虽然成本影响不大,但仍希望能够看到一切正常运行

要在本地运行时查看IP地址,请尝试以下操作:

using Microsoft.AspNetCore.Http;
然后:

String RemoteIP = ((DefaultHttpContext)req.Properties["HttpContext"])?.Connection?.RemoteIpAddress?.ToString();

这对我目前在Azure Functions V3.0中起作用。

很好,谢谢!大家都在说MS_HttpContext,但它不在我的函数中。所以这意味着你需要以某种方式将System.Web.dll引用塞进函数中?@Christoferohlson不幸的是,我认为确实如此。这不是函数具体来说,因为你在Web API或任何使用HttpRequestMessage的东西中都有相同的模式。我认为这不再有效了,我为所有用户提供了相同的IP集合,都在100*范围内。我在MSDN上看到过一篇帖子,其中有人确认最近发生了变化,现在他得到了相同的IP,即使MS_HttpContext以前工作过e@StevenElliott看看我在这里更新的答案AzureFunctions现在位于LoadBalancer后面,它与:csharp IPAddress result=null;if req.Headers.TryGetValueX-Forwarded-For,out StringValues values{var ipn=values.FirstOrDefault.Splitnew char[]{',}.FirstOrDefault.Splitnew char[]{':'}.FirstOrDefault;IPAddress.TryParseipn,out result;}如果result==null{result=req.HttpContext.Connection.RemoteIpAddress;}字符串IP=result?.ToString;已工作
String RemoteIP = ((DefaultHttpContext)req.Properties["HttpContext"])?.Connection?.RemoteIpAddress?.ToString();