Bagaimana cara saya mendapatkan alamat IP klien di ASP.NET CORE?

202

Bisakah Anda memberi tahu saya cara mendapatkan alamat IP klien di ASP.NET saat menggunakan MVC 6. Request.ServerVariables["REMOTE_ADDR"]tidak berfungsi.

Eadam
sumber
Contoh:httpContext.GetFeature<IHttpConnectionFeature>().RemoteIpAddress
Kiran Challa
Alasan penahanan tersedia di bagian bawah pertanyaan, "Ada terlalu banyak kemungkinan jawaban, atau jawaban yang baik akan terlalu panjang untuk format ini. Silakan tambahkan perincian untuk mempersempit set jawaban atau untuk mengisolasi masalah yang dapat dijawab dalam beberapa paragraf. "
Kevin Brown
12
Saya kira jawabannya tidak cukup panjang. Ini hal sederhana yang kami lakukan di versi lama MVC. Saya hanya bertanya bagaimana melakukannya dalam versi beta terbaru. Kedua, jika ada banyak jawaban, mengapa tidak ada orang yang mengarahkan saya ke SATU dari mereka. Infact, MVC 6 adalah beta dan saya pikir mereka bahkan tidak membaca pertanyaan dengan benar sebelum memegangnya.
eadam
Edit pertanyaan Anda yang menunjukkan lebih banyak dari apa yang Anda coba dan input / output yang jelas. jangan hanya mengeluh bahwa pertanyaan Anda sudah ditutup tanpa setidaknya berusaha memperbaikinya.
10
Hanya pemrogram dari domain yang sama yang harus menutup pertanyaan. Siapa pun yang bekerja di asp.net 5.0 hanya akan tahu apa yang saya minta dalam sepersekian detik. Kalian semua hanya menghukum saya karena mengirim pertanyaan sederhana.
eadam

Jawaban:

271

API telah diperbarui. Tidak yakin kapan itu berubah tetapi menurut Damien Edwards pada akhir Desember, Anda sekarang dapat melakukan ini:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;
David Peden
sumber
9
Itu RemoteIpAddressselalu nulluntuk saya, ketika saya mempublikasikan situs webnya di IIS dan mencatatnya di file.
A-Sharabiani
3
Sepertinya masalah ini diperbaiki di rc 2
Jon
12
Saya selalu mendapatkan 127.0.0.1 bahkan ketika saya menghubungkan dari jarak jauh
frostymarvelous
32
Ini mengembalikan ":: 1" untuk saya yang merupakan format IPv6. Bagaimana orang lain melihat 127.0.0.1?
Derek Greer
4
Apakah orang lain mendapatkan alamat IP lokal dari server IIS mereka kembali?
dave317
73

Dalam project.json menambahkan ketergantungan ke:

"Microsoft.AspNetCore.HttpOverrides": "1.0.0"

Di Startup.cs, dalam Configure()metode ini tambahkan:

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

Dan tentu saja:

using Microsoft.AspNetCore.HttpOverrides;

Lalu, saya bisa mendapatkan ip dengan menggunakan:

Request.HttpContext.Connection.RemoteIpAddress

Dalam kasus saya, ketika debugging di VS saya selalu menjadi localhost IpV6, tetapi ketika digunakan pada IIS saya selalu mendapatkan IP jarak jauh.

Beberapa tautan bermanfaat: Bagaimana cara saya mendapatkan alamat IP klien di ASP.NET CORE? dan RemoteIpAddress selalu nol

The ::1adalah mungkin karena:

Pemutusan koneksi di IIS, yang kemudian meneruskan ke Kestrel, server web v.next, jadi koneksi ke server web memang dari localhost. ( https://stackoverflow.com/a/35442401/5326387 )

Johna
sumber
6
Ini adalah jawaban yang benar, yang juga didokumentasikan pada dokumentasi resmi tentang proksi terbalik: docs.microsoft.com/en-us/aspnet/core/host-and-deploy/…
Melvyn
8
perlu menunjukkan bahwa "app.UseForwardedHeaders ..." perlu ditambahkan sebelum app.UseAuthentication (); line, jika Anda menggunakan indentity
netfed
1
Ini bekerja dengan sempurna dan saya telah menguji pada IIS yang di-host secara lokal dan pada Azure. Bekerja di kedua tempat.
ThomasCle
72

Beberapa logika fallback dapat ditambahkan untuk menangani keberadaan Load Balancer.

Selain itu, melalui inspeksi, X-Forwarded-Fortajuk tetap disetel meskipun tanpa Load Balancer (mungkin karena lapisan Kestrel tambahan?):

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

Asumsi _httpContextAccessordiberikan melalui DI.

crokusek
sumber
2
Ini adalah jawaban yang benar. Tidak ada satu cara untuk mengambil alamat IP, khususnya ketika aplikasi Anda berada di belakang Nginx, penyeimbang beban atau sesuatu seperti itu. Terima kasih!
Feu
@ jenis feu, karena AspNetCore dapat mengesampingkan properti RemoteIpAddress dengan header seperti X-Forwarded-For.
Mark Lopez
@crokusek ... mencoba menyesuaikan solusi Anda, tetapi VS memaksa saya ke kelas mengenkapsulasi kode ini statis. Apakah Anda memiliki kode ini di proyek aplikasi web Anda atau di perpustakaan kelas dalam solusinya?
dinotom
2 metode pertama harus dalam contoh yang menyediakan __httpContextAccessor (atau menyesuaikannya). Metode 2 string kedua ditarik dari kelas ekstensi statis terpisah.
crokusek
Ini adalah solusi yang baik terutama ketika aplikasi Anda menggunakan Kestrel dan di-host dengan Nginx di Linux.
Timothy Macharia
16

Anda dapat menggunakan IHttpConnectionFeatureuntuk mendapatkan informasi ini.

var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress;
Kiran Challa
sumber
Terima kasih atas jawabannya!
eadam
2
Apakah itu berfungsi untuk hosting Kestrel? Dalam demo saya, httpContext.GetFeature<IHttpConnectionFeature>()selalu demikian null.
Jerry Bian
2
@JerryBian menurut dokumen ini: github.com/aspnet/Docs/blob/master/aspnet/fundamentals/… , IHttpConnectionFeature tidak didukung di Kestrel (belum).
qbik
@JerryBian sekarang
David Peden
Pasti sudah ditinggalkan - versi @feradz bekerja untuk saya di RC-1
fiat
12
var remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;
feradz
sumber
6
Terlalu rumit. MVC sudah memanggil itu secara internal dan menempatkannya di bawah HttpContext.Connection.RemoteIpAddress.
Fred
@ Fred - versi Anda mengembalikan nol untuk saya di RC-1 - IIS dan Kestrel
fiat
7

Di ASP.NET 2.1, Di StartUp.cs Tambahkan Layanan Ini:

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

dan kemudian lakukan 3 langkah:

  1. Tentukan variabel dalam pengontrol MVC Anda

    private IHttpContextAccessor _accessor;
  2. DI ke dalam konstruktor pengendali

    public SomeController(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
  3. Ambil kembali Alamat IP

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()

Ini adalah bagaimana hal itu dilakukan.

hojjat.mi
sumber
2
Ini memberi saya :: 1. Asp.Net Core 2.2., Di localhost.
Stian
::1adalah localhost di IPv6. Setara IPv4 dari127.0.0.1
Andy
6

Ini berfungsi untuk saya (DotNetCore 2.1)

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

Dalam kasus saya, saya memiliki Aplikasi Web DotNet Core 2.2 yang berjalan di DigitalOcean dengan docker dan nginx sebagai proxy terbalik. Dengan kode ini di Startup.cs saya bisa mendapatkan IP klien

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 adalah ip yang saya dapatkan sebelum menggunakan

Request.HttpContext.Connection.RemoteIpAddress.ToString();
gorums
sumber
2

Pertama, di .Net Core 1.0 Tambahkan using Microsoft.AspNetCore.Http.Features;ke controller Kemudian di dalam metode yang relevan:

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

Saya membaca beberapa jawaban lain yang gagal dikompilasi karena menggunakan httpContext huruf kecil, memimpin VS untuk menambahkan menggunakan Microsoft.AspNetCore.Http, bukan menggunakan yang sesuai, atau dengan HttpContext (kompiler juga menyesatkan).

Orang
sumber
2

dapatkan ipaddress dan hostname di .net core

letakkan kode ini di controller

Ikuti langkah ini:

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

Saya menemukan bahwa, beberapa dari Anda menemukan bahwa alamat IP yang Anda dapatkan adalah ::: 1 atau 0.0.0.1

Ini adalah masalah karena Anda mencoba untuk mendapatkan IP dari mesin Anda sendiri, dan kebingungan C # yang mencoba mengembalikan IPv6.

Jadi, saya menerapkan jawaban dari @Johna ( https://stackoverflow.com/a/41335701/812720 ) dan @David ( https://stackoverflow.com/a/8597351/812720 ), Terima kasih kepada mereka!

dan di sini untuk solusinya:

  1. tambahkan Paket Microsoft.AspNetCore.HttpOverrides di Referensi Anda (Ketergantungan / Paket)

  2. tambahkan baris ini di 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. untuk mendapatkan IPAddress, gunakan kode ini di Controller.cs Anda

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

dan sekarang Anda bisa mendapatkan alamat IPv4 dari remoteIpAddress atau hasilnya

Sruit A.Suk
sumber
1

coba ini.

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

Berjalan .NET core(3.1.4) di IISbelakang Load balancer tidak berfungsi dengan solusi yang disarankan lainnya.

Membaca X-Forwarded-Forheader secara manual tidak.

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

Saya menjalankan paket mandiri menggunakan bundel hosting .

Aage
sumber
0

Menjalankan ASP.NET Core 2.1 di belakang Proxy reverse Traefik di Ubuntu, saya perlu mengatur IP gateway KnownProxiessetelah menginstal Microsoft.AspNetCore.HttpOverridespaket resmi

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

Menurut dokumentasi , ini diperlukan jika proxy terbalik tidak berjalan di localhost. The docker-compose.ymldari Traefik telah diberi alamat IP statis:

networks:
  my-docker-network:
    ipv4_address: 192.168.3.2

Atau, itu harus cukup untuk memastikan jaringan yang dikenal didefinisikan di sini untuk menentukan gateway di .NET Core.

Singa
sumber