首页 文章

如何在ASP.NET CORE中获取客户端IP地址?

提问于
浏览
111

在使用MVC 6时,能告诉我如何在ASP.NET中获取客户端IP地址吗? Request.ServerVariables["REMOTE_ADDR"] 不起作用 .

6 回答

  • 16

    API已更新 . 不确定它何时改变,但在12月下旬according to Damien Edwards,你现在可以这样做:

    var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;
    
  • 1

    可以添加一些回退逻辑来处理Load Balancer的存在 .

    此外,通过检查,即使没有Load Balancer,也可能无论如何都设置了 X-Forwarded-For 标头(可能是因为额外的Kestrel层?):

    public string GetRequestIP(bool tryUseXForwardHeader = true)
    {
        string ip = null;
    
        // todo support new "Forwarded" header (2014) https://en.wikipedia.org/wiki/X-Forwarded-For
    
        // X-Forwarded-For (csv list):  Using the First entry in the list seems to work
        // for 99% of cases however it has been suggested that a better (although tedious)
        // approach might be to read each IP from right to left and use the first public IP.
        // http://stackoverflow.com/a/43554000/538763
        //
        if (tryUseXForwardHeader)
            ip = GetHeaderValueAs<string>("X-Forwarded-For").SplitCsv().FirstOrDefault();
    
        // RemoteIpAddress is always null in DNX RC1 Update1 (bug).
        if (ip.IsNullOrWhitespace() && _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress != null)
            ip = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
    
        if (ip.IsNullOrWhitespace())
            ip = GetHeaderValueAs<string>("REMOTE_ADDR");
    
        // _httpContextAccessor.HttpContext?.Request?.Host this is the local host.
    
        if (ip.IsNullOrWhitespace())
            throw new Exception("Unable to determine caller's IP.");
    
        return ip;
    }
    
    public T GetHeaderValueAs<T>(string headerName)
    {
        StringValues values;
    
        if (_httpContextAccessor.HttpContext?.Request?.Headers?.TryGetValue(headerName, out values) ?? false)
        {
            string rawValues = values.ToString();   // writes out as Csv when there are multiple.
    
            if (!rawValues.IsNullOrWhitespace())
                return (T)Convert.ChangeType(values.ToString(), typeof(T));
        }
        return default(T);
    }
    
    public static List<string> SplitCsv(this string csvList, bool nullOrWhitespaceInputReturnsNull = false)
    {
        if (string.IsNullOrWhiteSpace(csvList))
            return nullOrWhitespaceInputReturnsNull ? null : new List<string>();
    
        return csvList
            .TrimEnd(',')
            .Split(',')
            .AsEnumerable<string>()
            .Select(s => s.Trim())
            .ToList();
    }
    
    public static bool IsNullOrWhitespace(this string s)
    {
        return String.IsNullOrWhiteSpace(s);
    }
    

    假设 _httpContextAccessor 是通过DI提供的 .

  • 45

    在project.json中添加依赖项:

    "Microsoft.AspNetCore.HttpOverrides": "1.0.0"
    

    Startup.cs 中,在 Configure() 方法中添加:

    app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                ForwardedHeaders.XForwardedProto
            });
    

    而且当然:

    using Microsoft.AspNetCore.HttpOverrides;
    

    然后,我可以通过使用以下方式获取IP:

    Request.HttpContext.Connection.RemoteIpAddress
    

    在我的情况下,当在VS中调试时我总是得到IpV6 localhost,但是当部署在IIS上时,我总是得到远程IP .

    一些有用的链接:How do I get client IP address in ASP.NET CORE?RemoteIpAddress is always null

    ::1 可能是因为:

    IIS终止连接,然后转发到v.next Web服务器Kestrel,因此与Web服务器的连接确实来自localhost . (https://stackoverflow.com/a/35442401/5326387)

  • 11

    您可以使用 IHttpConnectionFeature 获取此信息 .

    var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress;
    
  • 145
    var remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;
    
  • 40

    首先,在.Net Core 1.0中将 using Microsoft.AspNetCore.Http.Features; 添加到控制器然后在相关方法内:

    var ip = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress?.ToString();
    

    我读了几个其他无法编译的答案,因为它使用的是小写的httpContext,导致VS使用Microsoft.AspNetCore.Http添加,而不是使用适当的,或者使用HttpContext(编译器也是误导) .

相关问题