Internet enabled IIS Site always returning Local IP 互联网启用的 IIS 网站始终返回本地 IP

9 浏览
0 Comments

Internet enabled IIS Site always returning Local IP 互联网启用的 IIS 网站始终返回本地 IP

请问在使用MVC 6时,您能告诉我如何获取ASP.NET中的客户端IP地址吗?Request.ServerVariables["REMOTE_ADDR"]无效。

0
0 Comments

问题:Internet enabled IIS Site always returning Local IP

原因:

- 当应用程序位于负载均衡器之后时,无法正确获取客户端的 IP 地址。

- 即使没有负载均衡器,也会在请求中设置 X-Forwarded-For 头部。

解决方法:

- 可以添加一些回退逻辑来处理负载均衡器的存在。

- 可以尝试使用 X-Forwarded-For 头部来获取客户端的 IP 地址。

- 如果 X-Forwarded-For 头部不存在或为空,则尝试使用 RemoteIpAddress 属性来获取客户端的 IP 地址。

- 如果 RemoteIpAddress 属性也为空,则尝试使用 REMOTE_ADDR 头部来获取客户端的 IP 地址。

- 如果以上方法都无法获取客户端的 IP 地址,则抛出异常。

代码示例:

public string GetRequestIP(bool tryUseXForwardHeader = true)
{
    string ip = null;
    
    if (tryUseXForwardHeader)
        ip = GetHeaderValueAs("X-Forwarded-For").SplitCsv().FirstOrDefault();
    
    if (ip.IsNullOrWhitespace() && _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress != null)
        ip = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
    
    if (ip.IsNullOrWhitespace())
        ip = GetHeaderValueAs("REMOTE_ADDR");
    
    if (ip.IsNullOrWhitespace())
        throw new Exception("Unable to determine caller's IP.");
    
    return ip;
}
public T GetHeaderValueAs(string headerName)
{
    StringValues values;
    
    if (_httpContextAccessor.HttpContext?.Request?.Headers?.TryGetValue(headerName, out values) ?? false)
    {
        string rawValues = values.ToString();
        
        if (!rawValues.IsNullOrWhitespace())
            return (T)Convert.ChangeType(values.ToString(), typeof(T));
    }
    
    return default(T);
}
public static List SplitCsv(this string csvList, bool nullOrWhitespaceInputReturnsNull = false)
{
    if (string.IsNullOrWhiteSpace(csvList))
        return nullOrWhitespaceInputReturnsNull ? null : new List();
    
    return csvList
        .TrimEnd(',')
        .Split(',')
        .AsEnumerable()
        .Select(s => s.Trim())
        .ToList();
}
public static bool IsNullOrWhitespace(this string s)
{
    return String.IsNullOrWhiteSpace(s);
}

注意事项:

- `_httpContextAccessor` 应通过 DI 进行注入。

- 使用这种解决方法时,应用程序部署在 Kestrel 和 Nginx 上时效果良好。

- 如果配置不正确,可能会导致 IP 地址被伪造,因此需要注意安全性。

- 如果使用静态类中的扩展方法 IsNullOrWhitespace 和 SplitCsv,则应将其放在静态类中,其他方法可以在控制器的上下文中使用。

建议:

- 最好使用内置的 `UseForwardedHeaders` 中间件来处理 IP 地址的获取,具体参考文档。

0