430 Stimmen

Wie bekomme ich die Client-IP-Adresse eines Benutzers in ASP.NET?

Wir haben Request.UserHostAddress, um die IP-Adresse in ASP.NET zu bekommen, aber dies ist normalerweise die IP-Adresse des Internetanbieters des Benutzers, nicht genau die IP-Adresse des Benutzers auf dem Gerät, der zum Beispiel auf einen Link geklickt hat. Wie kann ich die echte IP-Adresse bekommen?

Zum Beispiel steht in einem Stack Overflow-Benutzerprofil: "Letzte Kontoaktivität: Vor 4 Stunden von 86.123.127.8", aber meine Geräte-IP-Adresse ist etwas anders. Wie kommt Stack Overflow an diese Adresse?

In einigen Web-Systemen gibt es eine IP-Adressprüfung für bestimmte Zwecke. Zum Beispiel kann mit einer bestimmten IP-Adresse ein Benutzer alle 24 Stunden nur 5 Klicks auf Download-Links haben. Diese IP-Adresse sollte eindeutig sein, nicht für einen Internetanbieter, der eine große Anzahl von Kunden oder Internetnutzern hat.

Habe ich das richtig verstanden?

4 Stimmen

Sie tun in der Regel dasselbe und funktionieren nicht korrekt für gemeinsam genutzte IP-Adressen. In diesem Bereich kann nicht viel getan werden.

0 Stimmen

Was ist das Problem, das Sie hier lösen möchten, warum glauben Sie, dass Sie die IP-Adresse benötigen?

4 Stimmen

Ich habe eine Anwendung, die spezifische Link-Klicks überprüft, und ein spezifischer Benutzer (nach IP) kann den Link an einem Tag nicht mehr als 5 Mal klicken. Das Problem ist, ob Request.UserHostAddress für eine Gruppe von Benutzern unter einem ISP oder Netzwerk oder für einen bestimmten Benutzer ist.

23voto

KMX Punkte 2481

Ich denke, ich sollte meine Erfahrung mit euch allen teilen. Nun, ich sehe in einigen Situationen REMOTE_ADDR wird dir nicht das liefern, wonach du suchst. Zum Beispiel, wenn du einen Lastenausgleicher im Hintergrund hast und versuchst, die IP des Clients zu bekommen, wirst du Probleme haben. Ich habe es mit meiner IP-Maskierungssoftware überprüft und auch mit meinen Kollegen in verschiedenen Kontinenten überprüft. Hier ist also meine Lösung.

Wenn ich die IP eines Clients wissen möchte, versuche ich jede mögliche Evidenz aufzugreifen, um festzustellen, ob sie eindeutig sind:

Hier habe ich eine weitere Server-Variable gefunden, die euch allen helfen könnte, wenn ihr die genaue IP der Client-Seite erhalten möchtet. Deshalb benutze ich: HTTP_X_CLUSTER_CLIENT_IP

HTTP_X_CLUSTER_CLIENT_IP gibt immer die genaue IP des Clients zurück. Falls es dir keinen Wert liefert, solltest du nach HTTP_X_FORWARDED_FOR suchen, da es der zweitbeste Kandidat ist, um dir die Client-IP zu liefern, und dann die Variable REMOTE_ADDR, die dir die IP zurückgeben kann oder auch nicht, aber für mich ist es das Beste, alle diese drei zu überwachen.

Ich hoffe, das hilft einigen Leuten.

0 Stimmen

Es muss gesagt werden, dass die `http_x_...`-Header leicht gefälscht werden können im Vergleich zur `remote_addr`-Variable. Und deshalb bleibt `remote_addr` die verlässlichste Quelle für die Client-IP-Adresse.

1 Stimmen

@CiroCorvino Sie haben Recht, aber wenn Ihre Website auf einem Server gehostet ist, der sich hinter dem Load Balancer befindet (wie ich bereits in meinem Beitrag erwähnt habe), liefert remote_addr nicht die IP, nach der Sie suchen. Ich habe erlebt, was Sie sagen, aber als ich die Lösung genauer untersucht habe, habe ich festgestellt, dass das, was ich gesagt habe, für mich am besten funktioniert.

0 Stimmen

Entschuldigung @KMX, ich verwende tatsächlich auch eine Kombination aus remote_addr und http_x_forwarded, um einige Annahmen über die Herkunft der Anfrage zu treffen. Wenn Sie Ihren Beitrag bearbeiten, aktualisiere ich meine Stimme.

18voto

dana Punkte 15935

Alle bisherigen Antworten berücksichtigen den nicht standardisierten, aber sehr verbreiteten X-Forwarded-For-Header. Es gibt einen standardisierten Forwarded-Header, der etwas schwieriger auszulesen ist. Einige Beispiele sind wie folgt:

Forwarded: for="_gazonk"
Forwarded: For="[2001:db8:cafe::17]:4711"
Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43
Forwarded: for=192.0.2.43, for=198.51.100.17

Ich habe eine Klasse geschrieben, die beide dieser Header berücksichtigt, um die IP-Adresse des Clients zu bestimmen.

using System;
using System.Web;

namespace Util
{
    public static class IP
    {
        public static string GetIPAddress()
        {
            return GetIPAddress(new HttpRequestWrapper(HttpContext.Current.Request));
        }

        internal static string GetIPAddress(HttpRequestBase request)
        {
            // Behandlung des standardisierten 'Forwarded'-Headers
            string forwarded = request.Headers["Forwarded"];
            if (!String.IsNullOrEmpty(forwarded))
            {
                foreach (string segment in forwarded.Split(',')[0].Split(';'))
                {
                    string[] pair = segment.Trim().Split('=');
                    if (pair.Length == 2 && pair[0].Equals("for", StringComparison.OrdinalIgnoreCase))
                    {
                        string ip = pair[1].Trim('"');

                        // IPv6-Adressen sind immer in eckigen Klammern eingebettet
                        int left = ip.IndexOf('['), right = ip.IndexOf(']');
                        if (left == 0 && right > 0)
                        {
                            return ip.Substring(1, right - 1);
                        }

                        // Entfernen des Ports von IPv4-Adressen
                        int colon = ip.IndexOf(':');
                        if (colon != -1)
                        {
                            return ip.Substring(0, colon);
                        }

                        // Diese werden IPv4-, "unknown"- und obfuszierte Adressen zurückgeben
                        return ip;
                    }
                }
            }

            // Behandlung des nicht standardisierten 'X-Forwarded-For'-Headers
            string xForwardedFor = request.Headers["X-Forwarded-For"];
            if (!String.IsNullOrEmpty(xForwardedFor))
            {
                return xForwardedFor.Split(',')[0];
            }

            return request.UserHostAddress;
        }
    }
}

Unten sind einige Unit-Tests aufgeführt, die ich zur Validierung meiner Lösung verwendet habe:

using System.Collections.Specialized;
using System.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UtilTests
{
    [TestClass]
    public class IPTests
    {
        [TestMethod]
        public void TestForwardedObfuscated()
        {
            var request = new HttpRequestMock("for=\"_gazonk\"");
            Assert.AreEqual("_gazonk", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv6()
        {
            var request = new HttpRequestMock("For=\"[2001:db8:cafe::17]:4711\"");
            Assert.AreEqual("2001:db8:cafe::17", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv4()
        {
            var request = new HttpRequestMock("for=192.0.2.60;proto=http;by=203.0.113.43");
            Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv4WithPort()
        {
            var request = new HttpRequestMock("for=192.0.2.60:443;proto=http;by=203.0.113.43");
            Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedMultiple()
        {
            var request = new HttpRequestMock("for=192.0.2.43, for=198.51.100.17");
            Assert.AreEqual("192.0.2.43", Util.IP.GetIPAddress(request));
        }
    }

    public class HttpRequestMock : HttpRequestBase
    {
        private NameValueCollection headers = new NameValueCollection();

        public HttpRequestMock(string forwarded)
        {
            headers["Forwarded"] = forwarded;
        }

        public override NameValueCollection Headers
        {
            get { return this.headers; }
        }
    }
}

1 Stimmen

Großartige Lösung zur Handhabung des standardisierten Forwarded-Headers.

18voto

Bat_Programmer Punkte 6431

Sie können verwenden:

System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.GetValue(0).ToString();

0 Stimmen

Tatsächlich habe ich verwendet, um die lokale Host-IP-Adresse zu erhalten System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).Ad‌​dressList[1].ToStrin‌​g();

0 Stimmen

Allerdings erhalte ich einen Fehler beim Ausführen davon in Fiddle Anforderung für die Berechtigung des Typs 'System.Net.DnsPermission, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' ist fehlgeschlagen.

5 Stimmen

OP fragt, wie man die IP-Adresse des entfernten Webbenutzers erhält, nicht seine eigene localhost-Adresse.

14voto

John Saunders Punkte 159011

IP-Adressen sind Teil der Netzwerkschicht im "siebenschichtigen Stapel". Die Netzwerkschicht kann machen, was sie will mit der IP-Adresse. Das passiert beispielsweise bei einem Proxy-Server, NAT, Relay oder ähnlichem.

Die Anwendungsschicht sollte in keiner Weise von der IP-Adresse abhängig sein. Insbesondere ist eine IP-Adresse nicht dazu gedacht, irgendetwas anderes als die Kennzeichnung eines Endes einer Netzwerkverbindung zu sein. Sobald eine Verbindung geschlossen ist, sollte man erwarten, dass sich die IP-Adresse (des gleichen Benutzers) ändert.

1 Stimmen

Das ist alles schön und gut, aber was machst du, wenn ein Kunde eines Multi-Tenant-Systems verlangt, dass die Konten ihrer Benutzer nur von einer bestimmten IP-Adresse aus angemeldet werden können?

1 Stimmen

Dann müssen sie Ihnen mitteilen, welche IP-Adresse Ihr Server sehen wird. Wenn sie möchten, dass eine bestimmte Adresse vorhanden ist, können sie nicht hinter einem NAT oder Ähnlichem liegen.

0 Stimmen

@RonnieOverby Ich befinde mich in derselben Situation. Ich muss wissen, von welcher IP aus sie eine Verbindung herstellen, und sie muss auf meiner Whitelist stehen. Dann kann die App bestimmte Funktionen basierend auf ihrer IP ein- oder ausschalten. Das ist es, was der Kunde möchte.

11voto

Tony Punkte 14821

Wenn Sie CloudFlare verwenden, können Sie diese Erweiterungsmethode ausprobieren:

public static class IPhelper
{
    public static string GetIPAddress(this HttpRequest Request)
    {
        if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();

        if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) return Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();

        return Request.UserHostAddress;
    }
}

dann

string IPAddress = Request.GetIPAddress();

2 Stimmen

Und mit F5 oder Palo Alto?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X