Làm cách nào để có địa chỉ IP của máy khách trong ASP.NET CORE?


202

Bạn có thể vui lòng cho tôi biết cách lấy địa chỉ IP của máy khách trong ASP.NET khi sử dụng MVC 6. Request.ServerVariables["REMOTE_ADDR"]không hoạt động.


Ví dụ:httpContext.GetFeature<IHttpConnectionFeature>().RemoteIpAddress
Kiran Challa

Lý do giữ có sẵn ở cuối câu hỏi, "Có quá nhiều câu trả lời có thể hoặc câu trả lời tốt sẽ quá dài cho định dạng này. Vui lòng thêm chi tiết để thu hẹp bộ câu trả lời hoặc cách ly một vấn đề có thể được trả lời trong một vài đoạn. "
Kevin Brown

12
Tôi không nghĩ câu trả lời là đủ dài. Đó là một điều đơn giản mà chúng tôi làm trong các phiên bản cũ hơn của MVC. Tôi chỉ hỏi làm thế nào để làm điều đó trong phiên bản beta mới nhất. Thứ hai, nếu có nhiều câu trả lời, Tại sao không ai chỉ cho tôi đến MỘT trong số họ. Nguyên vẹn, MVC 6 là bản beta và tôi nghĩ họ thậm chí không đọc đúng câu hỏi trước khi giữ nó.
eadam

Chỉnh sửa câu hỏi của bạn hiển thị nhiều hơn những gì bạn đã thử và đầu vào / đầu ra rõ ràng. đừng phàn nàn rằng câu hỏi của bạn đã bị đóng mà ít nhất là cố gắng cải thiện nó.

10
Chỉ các lập trình viên từ cùng một tên miền nên đóng câu hỏi. Bất cứ ai làm việc trong asp.net 5.0 sẽ chỉ cần biết những gì tôi đang hỏi trong một phần của giây. Phần còn lại của bạn chỉ là trừng phạt tôi vì chỉ đăng một câu hỏi đơn giản.
eadam

Câu trả lời:


271

API đã được cập nhật. Không chắc chắn khi nó thay đổi nhưng theo Damien Edwards vào cuối tháng 12, bây giờ bạn có thể làm điều này:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;

9
Điều RemoteIpAddressnày luôn luôn nulldành cho tôi, khi tôi xuất bản trang web của anh ấy trên IIS và đăng nhập nó trên một tập tin.
A-Sharabiani

3
Có vẻ như sự cố đã được khắc phục trong RC 2
Jon

12
Tôi luôn nhận được 127.0.0.1 ngay cả khi tôi kết nối từ xa
frostymarvelous

32
Đây là trả về ":: 1" cho tôi, đó là định dạng IPv6. Làm thế nào những người khác nhìn thấy 127.0.0.1?
Derek Greer

4
Có ai khác nhận được địa chỉ IP cục bộ của máy chủ IIS của họ được trả lại không?
dave317

72

Trong project.json thêm một phụ thuộc vào:

"Microsoft.AspNetCore.HttpOverrides": "1.0.0"

Trong Startup.cs, trong Configure()phương thức thêm:

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

Và tất nhiên:

using Microsoft.AspNetCore.HttpOverrides;

Sau đó, tôi có thể nhận được ip bằng cách sử dụng:

Request.HttpContext.Connection.RemoteIpAddress

Trong trường hợp của tôi, khi gỡ lỗi trong VS tôi luôn nhận được IpV6 localhost, nhưng khi được triển khai trên IIS tôi luôn nhận được IP từ xa.

Một số liên kết hữu ích: Làm thế nào để tôi có được địa chỉ IP của máy khách trong ASP.NET CORE? RemoteIpAddress luôn là null

::1thể là do:

Kết thúc kết nối tại IIS, sau đó chuyển tiếp đến Kestrel, máy chủ web v.next, vì vậy các kết nối đến máy chủ web thực sự là từ localhost. ( https://stackoverflow.com/a/35442401/5326387 )


6
Đây là câu trả lời đúng, đó cũng là tài liệu trên các tài liệu chính thức về proxy ngược lại: docs.microsoft.com/en-us/aspnet/core/host-and-deploy/...
Melvyn

8
cần phải chỉ ra rằng "app.UseForwardedHeaders ..." cần được thêm vào trước app.UseAuthentication (); trong trường hợp bạn sử dụng
thụt lề

1
Điều này hoạt động hoàn hảo và tôi đã thử nghiệm trên IIS được lưu trữ cục bộ và trên Azure. Hoạt động cả hai nơi.
ThomasCle

72

Một số logic dự phòng có thể được thêm vào để xử lý sự hiện diện của Load Balancer.

Ngoài ra, thông qua kiểm tra, X-Forwarded-Fortiêu đề tình cờ vẫn được đặt ngay cả khi không có Load Balancer (có thể do lớp Kestrel bổ sung?):

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);
}

Giả định _httpContextAccessorđược cung cấp thông qua DI.


2
Đây là câu trả lời đúng. Không có một cách duy nhất để lấy địa chỉ IP, đặc biệt khi ứng dụng của bạn đứng sau Nginx, bộ cân bằng tải hoặc một cái gì đó tương tự. Cảm ơn!
Feu

@feu loại, vì AspNetCore có thể ghi đè lên thuộc tính RemoteIpAddress bằng các tiêu đề như X-Forwarded-For.
Mark Lopez

@crokusek ... đang cố gắng điều chỉnh giải pháp của bạn, nhưng VS buộc tôi phải đến lớp đóng gói mã này tĩnh. Bạn có mã này trong dự án ứng dụng web của bạn hoặc trong một thư viện lớp trong giải pháp không?
dinotom

Hai phương thức đầu tiên phải ở trong một trường hợp cung cấp __httpContextAccessor (hoặc điều chỉnh nó). Các phương thức 2 chuỗi thứ hai được lấy từ một lớp mở rộng tĩnh riêng.
crokusek

Đây là một giải pháp tốt đặc biệt là khi ứng dụng của bạn sử dụng Kestrel và được lưu trữ với Nginx trên Linux.
Timothy Macharia

16

Bạn có thể sử dụng IHttpConnectionFeatuređể có được thông tin này.

var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress;

Cảm ơn câu trả lời!
eadam 18/03/2015

2
Nó có hoạt động cho lưu trữ Kestrel không? Trong bản demo của tôi, httpContext.GetFeature<IHttpConnectionFeature>()luôn luôn là như vậy null.
Jerry Bian

2
@JerryBian theo tài liệu này: github.com/aspnet/Docs/blob/master/aspnet/fundamentals/ chủ , IHttpConnectionFeature chưa được hỗ trợ trong Kestrel (chưa).
qbik

@JerryBian bây giờ
David Peden

Phải bị phản đối - phiên bản @feradz hoạt động với tôi trong RC-1
fiat

12
var remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;

6
Quá phức tạp. MVC đã gọi nó trong nội bộ và đặt nó dưới HttpContext.Connection.RemoteIpAddress.
Fred

@Fred - phiên bản của bạn trả về null cho tôi trong RC-1 - IIS và Kestrel
fiat

7

Trong ASP.NET 2.1, Trong StartUp.cs Thêm dịch vụ này:

services.AddHttpContextAccessor();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();

và sau đó làm 3 bước:

  1. Xác định một biến trong bộ điều khiển MVC của bạn

    private IHttpContextAccessor _accessor;
  2. DI vào hàm tạo của bộ điều khiển

    public SomeController(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
  3. Lấy địa chỉ IP

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()

Đây là cách nó được thực hiện.


2
Điều này mang lại cho tôi :: 1. Asp.Net Core 2.2., Trên localhost.
Stian

::1là localhost trong IPv6. Tương đương với IPv4 của127.0.0.1
Andy

6

Điều này làm việc cho tôi (DotNetCore 2.1)

[HttpGet]
public string Get() 
{
    var remoteIpAddress = HttpContext.Connection.RemoteIpAddress;
    return remoteIpAddress.ToString();
}

3

Trong trường hợp của tôi, tôi có Ứng dụng web DotNet Core 2.2 chạy trên DigitalOcean với docker và nginx làm proxy ngược. Với mã này trong Startup.cs tôi có thể lấy IP của máy khách

app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.All,
            RequireHeaderSymmetry = false,
            ForwardLimit = null,
            KnownNetworks = { new IPNetwork(IPAddress.Parse("::ffff:172.17.0.1"), 104) }
        });

:: ffff: 172.17.0.1 là ip mà tôi đã nhận được trước khi sử dụng

Request.HttpContext.Connection.RemoteIpAddress.ToString();

2

Đầu tiên, trong .Net Core 1.0 Thêm using Microsoft.AspNetCore.Http.Features;vào bộ điều khiển Sau đó bên trong phương thức có liên quan:

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

Tôi đã đọc một số câu trả lời khác không biên dịch được vì nó đang sử dụng httpContext chữ thường, dẫn đến việc VS thêm bằng cách sử dụng Microsoft.AspNetCore.Http, thay vì sử dụng thích hợp, hoặc với HTTPContext (trình biên dịch cũng bị đánh lừa).


2

nhận ipaddress và tên máy chủ trong lõi .net

đặt mã này trong bộ điều khiển

Thực hiện theo các bước sau:

var addlist = Dns.GetHostEntry(Dns.GetHostName());
string GetHostName = addlist.HostName.ToString();
string GetIPV6 = addlist.AddressList[0].ToString();
string GetIPV4 = addlist.AddressList[1].ToString();

2

Tôi thấy rằng, một số bạn thấy rằng địa chỉ IP bạn nhận được là ::: 1 hoặc 0.0.0.1

Đây là vấn đề do bạn cố gắng lấy IP từ máy của chính mình và sự nhầm lẫn của C # cố gắng trả lại IPv6.

Vì vậy, tôi triển khai câu trả lời từ @Johna ( https://stackoverflow.com/a/41335701/812720 ) và @David ( https://stackoverflow.com/a/8597351/812720 ), Cảm ơn họ!

và ở đây để giải quyết:

  1. thêm Gói Microsoft.AspNetCore.HttpOverrides trong Tài liệu tham khảo của bạn (Phụ thuộc / Gói)

  2. thêm dòng này vào Startup.cs

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // your current code
    
        // start code to add
        // to get ip address
        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });
        // end code to add
    
    }
  3. để nhận IPAddress, hãy sử dụng mã này trong bất kỳ Trình điều khiển nào của bạn.

    IPAddress remoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress;
    string result = "";
    if (remoteIpAddress != null)
    {
        // If we got an IPV6 address, then we need to ask the network for the IPV4 address 
        // This usually only happens when the browser is on the same machine as the server.
        if (remoteIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
        {
            remoteIpAddress = System.Net.Dns.GetHostEntry(remoteIpAddress).AddressList
    .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
        }
        result = remoteIpAddress.ToString();
    }

và bây giờ bạn có thể nhận địa chỉ IPv4 từ remoteIpAddress hoặc kết quả


1

thử cái này.

var host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (var ip in host.AddressList)
        {
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                 ipAddress = ip.ToString();
            }
        }

0

Chạy .NET core(3.1.4) IISphía sau bộ cân bằng tải không hoạt động với các giải pháp được đề xuất khác.

Đọc thủ công X-Forwarded-Fortiêu đề nào.

IPAddress ip;
var headers = Request.Headers.ToList();
if (headers.Exists((kvp) => kvp.Key == "X-Forwarded-For"))
{
    // when running behind a load balancer you can expect this header
    var header = headers.First((kvp) => kvp.Key == "X-Forwarded-For").Value.ToString();
    ip = IPAddress.Parse(header);
}
else
{
    // this will always have a value (running locally in development won't have the header)
    ip = Request.HttpContext.Connection.RemoteIpAddress;
}

Tôi đang chạy một khép kín gói bằng cách sử dụng gói lưu trữ .


0

Chạy ASP.NET Core 2.1 đằng sau Proxy đảo ngược Traefik trên Ubuntu, tôi cần đặt IP gateway của nó KnownProxiessau khi cài đặt Microsoft.AspNetCore.HttpOverridesgói chính thức

        var forwardedOptions = new ForwardedHeadersOptions {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor,
        };
        forwardedOptions.KnownProxies.Add(IPAddress.Parse("192.168.3.1"));
        app.UseForwardedHeaders(forwardedOptions);

Theo tài liệu , điều này là bắt buộc nếu proxy ngược không chạy trên localhost. Các docker-compose.ymlcủa Traefik đã gán một địa chỉ IP tĩnh:

networks:
  my-docker-network:
    ipv4_address: 192.168.3.2

Ngoài ra, nó là đủ để đảm bảo một mạng đã biết được xác định ở đây để chỉ định cổng của nó trong .NET Core.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.