我正在使用 Azure Functions 在 C# 中编写一个函数,并且需要获取调用该函数的客户端的 IP 地址,这可能吗?
6 回答
这是基于此处的答案。
#r "System.Web"
using System.Net;
using System.Web;
public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log)
{
string clientIP = ((HttpContextWrapper)req.Properties["MS_HttpContext"]).Request.UserHostAddress;
return req.CreateResponse(HttpStatusCode.OK, $"The client IP is {clientIP}");
}
你应该使用这些函数获取远程主机的IP地址
如果您调试预编译函数本地 request.Properties[RemoteEndpointMessageProperty.Name] 在 azure 上不可用,request.Properties["MS_HttpContext"] 不可用
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;
}
21.08.2018 更新: 现在 Azure Functions 位于 LoadBalancer 后面 --> 我们必须检查 Request-Headers 以确定正确的客户端 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();
}
这是基于我在 .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;
}
2019 年 10 月 18 日更新:
我尝试的解决方案更简单快捷,下面逐步提到。但是可以使用一些更冗长/棘手的替代方案@ https://docs.microsoft.com/en-us/azure/azure-monitor/app/ip-collection:
- 登录到 Azure 门户。
- 登录后在同一浏览器中打开一个新选项卡,然后拨打“<a href="http://Resources.Azure.Com" rel="nofollow noreferrer">http://Resources.Azure.Com”</li >
- 这是 Azure 后端服务门户,因此在进行更改时稍微小心一点会很棒。
- 从左侧面板展开 SUBSCRIPTIONS 部分,然后展开应用洞察资源所在的 Azure 订阅。
- 展开资源组部分并展开应用洞察资源所在的资源组。
- 展开 Providers 部分并找到 Microsoft.Insights 提供程序并将其展开。
- 展开组件部分,然后按名称查找并选择您的 App Insight 实例。
- 在右上角将您的模式从只读更改为读写。
- 单击 Rest API 调用上的 EDIT 按钮。
- 添加新的““DisableIpMasking”:属性部分的真实属性。
- 按 PUT 按钮应用更改。
- 现在您的 App Insight 已启用以开始收集客户端 IP 地址。
- 对函数进行一些查询。
- 大约 5 到 10 分钟后刷新并测试 App Insights 数据。
正如其他人已经提到的,旧的查看方法MS_HttpContext
不再有效。此外,虽然查看标头的方法X-Forwarded-For
确实有效,但它仅在 Azure 中发布后才有效 - 当您在本地运行时,它不会返回值。如果您更喜欢在本地进行测试以最大程度地减少任何潜在的成本影响,但仍然希望能够看到一切正常运行,这可能很重要。
即使在本地运行时也要查看 IP 地址,请尝试以下操作:
using Microsoft.AspNetCore.Http;
进而:
String RemoteIP = ((DefaultHttpContext)req.Properties["HttpContext"])?.Connection?.RemoteIpAddress?.ToString();
这目前在 Azure Functions V3.0 中为我工作。