ASP.NET CORE'da istemci IP adresini nasıl alabilirim?


206

MVC 6 kullanılırken ASP.NET'te istemci IP adresini nasıl alacağınızı lütfen bana bildirir misiniz Request.ServerVariables["REMOTE_ADDR"].


Örnek:httpContext.GetFeature<IHttpConnectionFeature>().RemoteIpAddress
Kiran Challa

Bekletme nedeni, "Çok fazla olası yanıt var veya bu biçim için iyi yanıtlar çok uzun olabilir." birkaç paragraf. "
Kevin Brown

12
Cevabın yeterince uzun olduğunu sanmıyorum. MVC'nin eski sürümlerinde yaptığımız basit bir şey. En son beta sürümünde nasıl yapılacağını sordum. İkincisi, çok fazla cevap varsa, Neden kimse beni sadece BİRİNİ işaret etmiyor? Infact, MVC 6 beta ve sanırım sormadan önce soruyu düzgün okumadıklarını düşünüyorum.
eadam

Sorunuzu, denediklerinizin daha fazlasını ve net bir giriş / çıkış göstererek düzenleyin. sorunuzu en azından iyileştirmeye çalışmadan kapatıldığından şikayet etmeyin.

10
Yalnızca aynı etki alanındaki programcılar soruyu kapatmalıdır. Asp.net 5.0 çalışan herkes sadece bir saniye içinde ne istediğimi bilecek. Geri kalanınız sadece basit bir soru yayınladığım için beni cezalandırıyorsunuz.
eadam

Yanıtlar:


276

API güncellendi. Ne zaman değiştiğinden emin değilim ama Aralık sonunda Damien Edwards'a göre , şimdi bunu yapabilirsiniz:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;

9
RemoteIpAddressHep nullben IIS üzerinde o web sitesi yayınlamak ve bir dosya üzerinde bu oturum açtığınızda, benim için.
A-Sharabiani

3
Sorun rc 2'de giderildi gibi görünüyor
Jon

12
Uzaktan bağlandığımda bile her zaman 127.0.0.1 alıyorum
frostymarvelous

33
IPv6 biçimi olan benim için ":: 1" döndürüyor. Diğerleri 127.0.0.1'i nasıl görüyor?
Derek Greer

4
IIS sunucusunun yerel IP adresini döndüren başka kimse var mı?
dave317

73

Project.json içinde aşağıdakilere bir bağımlılık ekleyin:

"Microsoft.AspNetCore.HttpOverrides": "1.0.0"

İçinde Startup.cs, Configure()yöntemde ekleyin:

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

Ve tabi ki:

using Microsoft.AspNetCore.HttpOverrides;

Sonra kullanarak ip alabilir:

Request.HttpContext.Connection.RemoteIpAddress

Benim durumumda, VS hata ayıklama her zaman IpV6 localhost var, ama bir IIS üzerinde dağıtıldığında her zaman uzak IP var.

Bazı yararlı bağlantılar: ASP.NET CORE'da istemci IP adresini nasıl alabilirim? ve RemoteIpAddress her zaman boştur

::1Belki taşımaktadır:

IIS'de bağlantıların sonlandırılması, daha sonra v.next web sunucusu olan Kestrel'e iletilir, böylece web sunucusuna bağlantılar gerçekten de yerel ana bilgisayardan olur. ( https://stackoverflow.com/a/35442401/5326387 )


6
Bu doğru yanıttır ve ters proxy'ler hakkındaki resmi belgelerde de belgelenmiştir: docs.microsoft.com/en-us/aspnet/core/host-and-deploy/…
Melvyn

8
appUygulamaAuthentication () 'dan önce "app.UseForwardedHeaders ..." eklenmesi gerektiğini belirtmek gerekir; satırında,
girintiyi

1
Bu mükemmel çalıştı ve yerel olarak barındırılan IIS ve Azure üzerinde test ettik. Her iki yerde de çalışır.
ThomasCle

72

Bir Yük Dengeleyicinin varlığını ele almak için bir geri dönüş mantığı eklenebilir.

Ayrıca, inceleme yoluyla, X-Forwarded-Forbaşlık bir Yük Dengeleyici olmadan bile yine de ayarlanır (muhtemelen ek Kestrel katmanı nedeniyle mi?):

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

Varsayımlar _httpContextAccessorDI yoluyla sağlandı.


2
Bu doğru cevap. IP adresini almanın tek bir yolu yoktur, özellikle uygulamanız bir Nginx, bir yük dengeleyici veya bunun gibi bir şeyin arkasındaysa. Teşekkürler!
Feu

AspfeCore, X-Forwarded-For gibi üstbilgilerle RemoteIpAddress özelliğini geçersiz kılabileceğinden, @feu türüne benzer.
Mark Lopez

@crokusek ... çözümünüzü uyarlamaya çalışıyor ama VS beni bu kodu statik olarak kapsayan sınıfa zorluyor. Bu kodu web uygulaması projenizde veya çözümdeki bir sınıf kitaplığında var mı?
dinotom

İlk 2 yöntem __httpContextAccessor sağlayan (veya uyarlayan) bir örnek olmalıdır. İkinci 2 dize yöntemi ayrı bir statik uzantı sınıfından alınmıştır.
crokusek

Bu özellikle uygulamanız Kestrel kullanıyorsa ve Linux'ta Nginx ile barındırılıyorsa iyi bir çözümdür.
Timothy Macharia

16

IHttpConnectionFeatureBu bilgiyi almak için 'i kullanabilirsiniz .

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

Cevap için teşekkürler!
eadam

2
Kestrel hosting için çalışıyor mu? Demomda httpContext.GetFeature<IHttpConnectionFeature>()hep öyle ol null.
Jerry Bian

2
@JerryBian bu dokümana göre: github.com/aspnet/Docs/blob/master/aspnet/fundamentals/… , IHttpConnectionFeature Kestrel'de (henüz) desteklenmiyor.
qbik

@JerryBian şimdi
David Peden

Onaylanmamış olmalı - @feradz sürümü RC-1'de benim için çalışıyor
fiat

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

6
Aşırı karmaşık. MVC zaten bunu dahili olarak çağırır ve altına koyar HttpContext.Connection.RemoteIpAddress.
Fred

@Fred - RC-1'de sürümünüz benim için null döndürüyor - IIS ve Kestrel
fiat

7

Bu benim için çalışıyor (DotNetCore 2.1)

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

7

ASP.NET 2.1'de StartUp.cs Bu Hizmetleri Ekle:

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

ve sonra 3 adım yapın:

  1. MVC denetleyicinizde bir değişken tanımlayın

    private IHttpContextAccessor _accessor;
  2. DI kontrolörün yapıcısına

    public SomeController(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
  3. IP Adresini Alma

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()

İşte böyle yapılır.


2
Bu bana :: 1 verir. Asp.Net Core 2.2., Localhost üzerinde.
Stian

::1IPv6'daki localhost. IPv4 eşdeğeri127.0.0.1
Andy

3

Benim durumumda, docker ve ters proxy olarak nginx ile DigitalOcean üzerinde çalışan DotNet Core 2.2 Web Uygulaması var. Startup.cs içindeki bu kod ile istemci IP'sini alabilirim

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 kullanmadan önce aldığım ipti

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

2

İlk olarak .Net Core 1.0'da using Microsoft.AspNetCore.Http.Features;Denetleyiciye ekleyin Daha sonra ilgili yöntemin içinde:

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

Küçük bir httpContext kullanarak derleme başarısız oldu, VS uygun kullanım yerine veya HttpContext (derleyici de yanıltıcı) yerine Microsoft.AspNetCore.Http kullanarak eklemek için yol açan derleme başarısız diğer birkaç cevap okudum.


2

.net çekirdeğinde ipadresi ve ana bilgisayar adı al

bu kodu denetleyiciye koy

Bu adımları takip et:

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

2

Bazılarınız, aldığınız IP adresinin ::: 1 veya 0.0.0.1 olduğunu buldum.

Bu sorun, kendi makinenizden IP almaya çalışmanız ve IPv6'yı döndürmeye çalışan C # karışıklığı nedeniyle sorun.

Bu yüzden, @Johna ( https://stackoverflow.com/a/41335701/812720 ) ve @David ( https://stackoverflow.com/a/8597351/812720 ) ' den yanıtı uyguladım , teşekkürler!

ve burada çözüm:

  1. Referanslarınıza Microsoft.AspNetCore.HttpOverrides Paketini ekleyin (Bağımlılıklar / Paketler)

  2. bu satırı Startup.cs dosyasına ekle

    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. IPAddress almak için bu kodu Controller.cs dosyalarınızdan herhangi birinde kullanı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();
    }

ve şimdi remoteIpAddress veya sonuçtan IPv4 adresi alabilirsiniz


1

bunu dene.

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

0

Koşu .NET coreüzerinde (3.1.4) IISbir yük dengeleyici arkasında başka önerilen çözümler ile çalışma yoktu.

X-Forwarded-ForBaşlığı manuel olarak okur .

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

Hosting paketini kullanarak bağımsız bir paket çalıştırıyorum .


0

Ubuntu'da bir Traefik ters Proxy'nin arkasında ASP.NET Core 2.1 çalıştırırken KnownProxies, resmi Microsoft.AspNetCore.HttpOverridespaketi yükledikten sonra ağ geçidi IP'sini ayarlamam gerekiyor

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

Belgelere göre , ters proxy localhost üzerinde çalışmıyorsa bu gereklidir. docker-compose.ymlTraefik bir statik IP adresi atanır etti:

networks:
  my-docker-network:
    ipv4_address: 192.168.3.2

Alternatif olarak, ağ geçidini .NET Core'da belirtmek için burada bilinen bir ağın tanımlandığından emin olmak yeterli olmalıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.