Wie erhalte ich die Client-IP-Adresse in ASP.NET CORE?

202

Können Sie bitte lassen Sie mich wissen , wie Adresse Client - IP in ASP.NET zu erhalten , wenn mit MVC 6. Request.ServerVariables["REMOTE_ADDR"]funktioniert nicht.

eadam
quelle
Beispiel:httpContext.GetFeature<IHttpConnectionFeature>().RemoteIpAddress
Kiran Challa
Der Haltegrund ist am Ende der Frage verfügbar: "Es gibt entweder zu viele mögliche Antworten, oder gute Antworten wären für dieses Format zu lang. Bitte fügen Sie Details hinzu, um den Antwortsatz einzugrenzen oder ein Problem zu isolieren, das beantwortet werden kann ein paar Absätze. "
Kevin Brown
12
Ich denke nicht, dass die Antwort lang genug ist. Es ist eine einfache Sache, die wir in den älteren Versionen von MVC machen. Ich habe gerade gefragt, wie es in der neuesten Beta-Version geht. Zweitens, wenn es viele Antworten gibt, warum weist mich niemand einfach auf den EINEN von ihnen hin? Tatsächlich ist MVC 6 Beta und ich denke, sie haben die Frage nicht einmal richtig gelesen, bevor sie sie gehalten haben.
eadam
Bearbeiten Sie Ihre Frage, indem Sie mehr von dem, was Sie versucht haben, und eine klare Eingabe / Ausgabe anzeigen. Beschweren Sie sich nicht nur, dass Ihre Frage geschlossen wurde, ohne zumindest zu versuchen , sie zu verbessern.
10
Nur Programmierer aus derselben Domäne sollten die Frage schließen. Jeder, der in asp.net 5.0 arbeitet, weiß einfach in Sekundenbruchteilen, was ich frage. Der Rest von euch bestraft mich nur dafür, dass ich nur eine einfache Frage gestellt habe.
eadam

Antworten:

271

Die API wurde aktualisiert. Ich bin mir nicht sicher, wann es sich geändert hat, aber laut Damien Edwards Ende Dezember können Sie dies jetzt tun:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;
David Peden
quelle
9
Das RemoteIpAddressist immer nullfür mich, wenn ich die Website auf IIS veröffentliche und diese in einer Datei protokolliere.
A-Sharabiani
3
Sieht aus wie das Problem in RC 2
Jon
12
Ich bekomme immer 127.0.0.1, auch wenn ich mich aus der Ferne verbinde
frostymarvelous
32
Dies gibt für mich ":: 1" zurück, was das IPv6-Format ist. Wie sehen andere 127.0.0.1?
Derek Greer
4
Bekommt jemand anderes die lokale IP-Adresse seines IIS-Servers zurück?
Dave317
72

Fügen Sie in project.json eine Abhängigkeit hinzu zu:

"Microsoft.AspNetCore.HttpOverrides": "1.0.0"

In Startup.csder Configure()Methode hinzufügen:

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

Und natürlich:

using Microsoft.AspNetCore.HttpOverrides;

Dann könnte ich die IP bekommen mit:

Request.HttpContext.Connection.RemoteIpAddress

In meinem Fall bekam ich beim Debuggen in VS immer IpV6 localhost, aber wenn ich auf einem IIS bereitgestellt wurde, bekam ich immer die Remote-IP.

Einige nützliche Links: Wie erhalte ich die Client-IP-Adresse in ASP.NET CORE? und RemoteIpAddress ist immer null

Das ::1liegt vielleicht an:

Verbindungsbeendigung bei IIS, die dann an Kestrel, den v.next-Webserver, weitergeleitet wird, sodass Verbindungen zum Webserver tatsächlich von localhost erfolgen. ( https://stackoverflow.com/a/35442401/5326387 )

Johna
quelle
6
Dies ist die richtige Antwort, die auch in der offiziellen Dokumentation über Reverse-Proxys dokumentiert ist: docs.microsoft.com/en-us/aspnet/core/host-and-deploy/…
Melvyn
8
müssen darauf hinweisen, dass die "app.UseForwardedHeaders ..." vor der app.UseAuthentication () hinzugefügt werden muss; line, falls Sie indentity verwenden
netfed
1
Dies hat perfekt funktioniert und ich habe getestet, dass es sich um lokal gehostetes IIS und Azure handelt. Funktioniert an beiden Orten.
ThomasCle
72

Einige Fallback-Logik kann hinzugefügt werden, um das Vorhandensein eines Load Balancers zu behandeln.

Durch Inspektion wird der X-Forwarded-ForHeader auch ohne Load Balancer gesetzt (möglicherweise aufgrund einer zusätzlichen Kestrel-Ebene?):

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

Angenommen, _httpContextAccessorwurde durch DI bereitgestellt.

crokusek
quelle
2
DAS ist die richtige Antwort. Es gibt keine einzige Möglichkeit, die IP-Adresse abzurufen, insbesondere wenn sich Ihre App hinter einem Nginx, einem Load Balancer oder ähnlichem befindet. Vielen Dank!
Feu
@feu Art, da AspNetCore die RemoteIpAddress-Eigenschaft mit Headern wie X-Forwarded-For überschreiben kann.
Mark Lopez
@crokusek ... versucht, Ihre Lösung anzupassen, aber VS zwingt mich zu der Klasse, die diesen Code statisch kapselt. Haben Sie diesen Code in Ihrem Web-App-Projekt oder in einer Klassenbibliothek in der Lösung?
Dinotom
Die ersten beiden Methoden sollten sich in einer Instanz befinden, die __httpContextAccessor bereitstellt (oder anpasst). Die zweiten beiden Zeichenfolgenmethoden wurden aus einer separaten statischen Erweiterungsklasse abgerufen.
Crokusek
Dies ist eine gute Lösung, insbesondere wenn Ihre App Kestrel verwendet und mit Nginx unter Linux gehostet wird.
Timothy Macharia
16

Sie können das verwenden IHttpConnectionFeature, um diese Informationen zu erhalten.

var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress;
Kiran Challa
quelle
Danke für die Antwort!
eadam
2
Funktioniert es für Kestrel Hosting? httpContext.GetFeature<IHttpConnectionFeature>()Sei in meiner Demo immer null.
Jerry Bian
2
@JerryBian gemäß diesem Dokument: github.com/aspnet/Docs/blob/master/aspnet/fundamentals/… , IHttpConnectionFeature wird in Kestrel (noch) nicht unterstützt.
QBIK
@ JerryBian ist es jetzt
David Peden
Muss veraltet gewesen sein - @feradz Version funktioniert für mich in RC-1
Fiat
12
var remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;
feradz
quelle
6
Übermäßig kompliziert. MVC ruft das bereits intern auf und legt es unter HttpContext.Connection.RemoteIpAddress.
Fred
@Fred - Ihre Version gibt null für mich in RC-1 - IIS und Kestrel
Fiat
7

Fügen Sie in ASP.NET 2.1 in StartUp.cs diese Dienste hinzu:

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

und dann 3 Schritte machen:

  1. Definieren Sie eine Variable in Ihrem MVC-Controller

    private IHttpContextAccessor _accessor;
  2. DI in den Konstruktor der Steuerung

    public SomeController(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
  3. Rufen Sie die IP-Adresse ab

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()

So wird es gemacht.

hojjat.mi
quelle
2
Das gibt mir :: 1. Asp.Net Core 2.2., Auf localhost.
Stian
::1ist localhost in IPv6. Das IPv4-Äquivalent von127.0.0.1
Andy
6

Das funktioniert bei mir (DotNetCore 2.1)

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

In meinem Fall läuft DotNet Core 2.2 Web App auf DigitalOcean mit Docker und Nginx als Reverse-Proxy. Mit diesem Code in Startup.cs kann ich die Client-IP erhalten

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 war die IP, die ich vor der Verwendung erhalten habe

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

Zuerst in .Net Core 1.0 using Microsoft.AspNetCore.Http.Features;Zum Controller hinzufügen Dann innerhalb der entsprechenden Methode:

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

Ich habe mehrere andere Antworten gelesen, die nicht kompiliert werden konnten, weil ein httpContext in Kleinbuchstaben verwendet wurde. Dies führte dazu, dass der VS mithilfe von Microsoft.AspNetCore.Http anstelle der entsprechenden Verwendung oder mit HttpContext hinzugefügt wurde (der Compiler ist ebenfalls irreführend).

Kerl
quelle
2

Holen Sie sich die IP-Adresse und den Hostnamen im .net-Kern

Geben Sie diesen Code in die Steuerung ein

Folge diesen Schritten:

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
quelle
2

Ich habe festgestellt, dass einige von Ihnen festgestellt haben, dass die IP-Adresse, die Sie erhalten, ::: 1 oder 0.0.0.1 ist

Dies ist das Problem, weil Sie versuchen, IP von Ihrem eigenen Computer abzurufen, und die Verwirrung von C #, die versucht, IPv6 zurückzugeben.

Also implementiere ich die Antwort von @Johna ( https://stackoverflow.com/a/41335701/812720 ) und @David ( https://stackoverflow.com/a/8597351/812720 ). Danke an sie!

und hier zur Lösung:

  1. Fügen Sie das Microsoft.AspNetCore.HttpOverrides-Paket in Ihre Referenzen ein (Abhängigkeiten / Pakete).

  2. Fügen Sie diese Zeile in Startup.cs hinzu

    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. Verwenden Sie diesen Code in einer Ihrer Controller.cs, um IPAddress zu erhalten

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

und jetzt können Sie die IPv4-Adresse von remoteIpAddress oder result erhalten

Obst A.Suk
quelle
1

Versuche dies.

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

Das Ausführen .NET core(3.1.4) IIShinter einem Load Balancer funktionierte nicht mit anderen vorgeschlagenen Lösungen.

Das manuelle Lesen des X-Forwarded-ForHeaders funktioniert.

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

Ich verwende ein eigenständiges Paket mit dem Hosting- Paket .

Aage
quelle
0

Wenn ich ASP.NET Core 2.1 hinter einem Traefik-Reverse-Proxy unter Ubuntu ausführe, muss ich KnownProxiesnach der Installation des offiziellen Microsoft.AspNetCore.HttpOverridesPakets die Gateway-IP festlegen

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

Laut Dokumentation ist dies erforderlich, wenn der Reverse-Proxy nicht auf localhost ausgeführt wird. The docker-compose.ymlof Traefik hat eine statische IP-Adresse vergeben:

networks:
  my-docker-network:
    ipv4_address: 192.168.3.2

Alternativ sollte es ausreichen, sicherzustellen, dass hier ein bekanntes Netzwerk definiert ist, um sein Gateway in .NET Core anzugeben.

Löwe
quelle