Come posso ottenere l'indirizzo IP del client in ASP.NET CORE?


206

Potete per favore fatemi sapere come ottenere l'indirizzo IP del client in ASP.NET quando si utilizza MVC 6. Request.ServerVariables["REMOTE_ADDR"]non funziona.


Esempio:httpContext.GetFeature<IHttpConnectionFeature>().RemoteIpAddress
Kiran Challa,

Il motivo della sospensione è disponibile nella parte inferiore della domanda "Esistono troppe risposte possibili o risposte buone sarebbero troppo lunghe per questo formato. Aggiungi dettagli per restringere il set di risposte o isolare un problema a cui è possibile rispondere alcuni paragrafi ".
Kevin Brown,

12
Non credo che la risposta sia abbastanza lunga. È una cosa semplice che facciamo nelle versioni precedenti di MVC. Ho appena chiesto come farlo nell'ultima versione beta. In secondo luogo, se ci sono molte risposte, perché nessuno mi indica semplicemente UNO di loro. Infatti, MVC 6 è beta e penso che non abbiano nemmeno letto correttamente la domanda prima di tenerla.
eadam,

Modifica la tua domanda mostrando più di quello che hai provato e un chiaro input / output. non lamentarti solo che la tua domanda è stata chiusa senza almeno cercare di migliorarla.

10
Solo i programmatori dello stesso dominio dovrebbero chiudere la domanda. Chiunque lavori in asp.net 5.0 saprà semplicemente cosa sto chiedendo in una frazione di secondo. Il resto di voi mi sta solo punendo per aver postato solo una semplice domanda.
eadam,

Risposte:


276

L'API è stata aggiornata. Non sono sicuro quando è cambiato, ma secondo Damien Edwards a fine dicembre, ora puoi farlo:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;

9
Lo RemoteIpAddressè sempre nullper me, quando pubblico il suo sito Web su IIS e lo registro su un file.
A-Sharabiani,

3
Sembra che il problema sia stato risolto in rc 2
Jon il

12
Ricevo sempre 127.0.0.1 anche quando mi collego da remoto
frostymarvelous,

33
Questo sta restituendo ":: 1" per me che è il formato IPv6. Come vedono gli altri 127.0.0.1?
Derek Greer,

4
Qualcun altro ottiene l'indirizzo IP locale del proprio server IIS restituito?
dave317,

73

In project.json aggiungi una dipendenza a:

"Microsoft.AspNetCore.HttpOverrides": "1.0.0"

In Startup.cs, nel Configure()metodo aggiungi:

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

Ed ovviamente:

using Microsoft.AspNetCore.HttpOverrides;

Quindi, potrei ottenere l'ip usando:

Request.HttpContext.Connection.RemoteIpAddress

Nel mio caso, durante il debug in VS ho sempre ricevuto localhost IpV6, ma quando distribuito su un IIS ho sempre l'IP remoto.

Alcuni link utili: Come posso ottenere l'indirizzo IP del client in ASP.NET CORE? e RemoteIpAddress è sempre nullo

Il ::1'forse a causa di:

Terminazione delle connessioni su IIS, che quindi inoltra a Kestrel, il server Web v.next, quindi le connessioni al server Web provengono effettivamente da localhost. ( https://stackoverflow.com/a/35442401/5326387 )


6
Questa è la risposta corretta, che è anche documentata sulla documentazione ufficiale sui proxy inversi: docs.microsoft.com/en-us/aspnet/core/host-and-deploy/…
Melvyn,

8
è necessario sottolineare che "app.UseForwardedHeaders ..." deve essere aggiunto prima dell'app.UseAuthentication (); linea, nel caso in cui usi indentity
netfed il

1
Funzionava perfettamente e ho testato su IIS ospitato localmente e su Azure. Funziona in entrambi i posti.
ThomasCle

72

È possibile aggiungere una certa logica di fallback per gestire la presenza di un bilanciamento del carico.

Inoltre, attraverso l'ispezione, l' X-Forwarded-Forintestazione sembra essere impostata comunque anche senza un bilanciamento del carico (forse a causa del livello Kestrel aggiuntivo?):

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

Presuppone è _httpContextAccessorstato fornito tramite DI.


2
Questa è la risposta esatta. Non c'è un solo modo per recuperare l'indirizzo IP, specialmente quando la tua app è dietro un Nginx, un bilanciamento del carico o qualcosa del genere. Grazie!
Feu,

@feu tipo di, poiché AspNetCore può sovrascrivere la proprietà RemoteIpAddress con intestazioni come X-Forwarded-For.
Mark Lopez,

@crokusek ... cercando di adattare la tua soluzione, ma VS mi costringe alla classe che incapsula questo codice statico. Hai questo codice nel tuo progetto di app web o in una libreria di classi nella soluzione?
cena del

I primi 2 metodi dovrebbero essere in un'istanza che fornisce __httpContextAccessor (o adattarlo). I secondi metodi a 2 stringhe sono stati estratti da una classe di estensioni statiche separata.
crokusek,

Questa è una buona soluzione soprattutto quando la tua app utilizza Kestrel ed è ospitata con Nginx su Linux.
Timothy Macharia,

16

È possibile utilizzare il IHttpConnectionFeatureper ottenere queste informazioni.

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

Grazie per la risposta!
eadam,

2
Funziona con l'hosting Kestrel? Nella mia demo, httpContext.GetFeature<IHttpConnectionFeature>()sii sempre null.
Jerry Bian,

2
@JerryBian secondo questo documento: github.com/aspnet/Docs/blob/master/aspnet/fundamentals/… , IHttpConnectionFeature non è supportato in Kestrel (ancora).
qbik,

@JerryBian adesso
David Peden,

Deve essere stato deprecato - la versione @feradz funziona per me in RC-1
fiat

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

6
Troppo complicato. MVC lo chiama già internamente e lo mette sotto HttpContext.Connection.RemoteIpAddress.
Fred,

@Fred - la tua versione restituisce null per me in RC-1 - IIS e Kestrel
fiat

7

Questo funziona per me (DotNetCore 2.1)

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

7

In ASP.NET 2.1, In StartUp.cs Aggiungi questo servizio:

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

e quindi fai 3 passaggi:

  1. Definire una variabile nel controller MVC

    private IHttpContextAccessor _accessor;
  2. DI nel costruttore del controller

    public SomeController(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
  3. Recupera l'indirizzo IP

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()

Ecco come si fa.


2
Questo mi dà :: 1. Asp.Net Core 2.2., Su localhost.
Stian,

::1è localhost in IPv6. L'equivalente IPv4 di127.0.0.1
Andy

3

Nel mio caso, ho DotNet Core 2.2 Web App in esecuzione su DigitalOcean con docker e nginx come proxy inverso. Con questo codice in Startup.cs posso ottenere l'IP client

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 era l'ip che stavo ottenendo prima di usare

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

2

In primo luogo, in .Net Core 1.0 Aggiungi using Microsoft.AspNetCore.Http.Features;al controller Quindi all'interno del metodo pertinente:

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

Ho letto diverse altre risposte che non sono riuscite a compilare perché utilizzava un httpContext minuscolo, portando il VS ad aggiungerlo usando Microsoft.AspNetCore.Http, invece dell'uso appropriato, o con HttpContext (anche il compilatore è fuorviante).


2

ottenere ipaddress e hostname in .net core

mettere questo codice nel controller

Segui questi passi:

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

2

Ho scoperto che, alcuni di voi hanno scoperto che l'indirizzo IP che ottenete è ::: 1 o 0.0.0.1

Questo è il problema a causa del tentativo di ottenere IP dal proprio computer e della confusione di C # che tenta di restituire IPv6.

Quindi, implemento la risposta di @Johna ( https://stackoverflow.com/a/41335701/812720 ) e @David ( https://stackoverflow.com/a/8597351/812720 ), Grazie a loro!

e qui alla soluzione:

  1. aggiungi il pacchetto Microsoft.AspNetCore.HttpOverrides nei tuoi riferimenti (dipendenze / pacchetti)

  2. aggiungi questa riga in 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. per ottenere IPAddress, utilizzare questo codice in qualsiasi Controller.cs

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

e ora puoi ottenere l'indirizzo IPv4 da remoteIpAddress o dal risultato


1

prova questo.

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

0

L'esecuzione .NET core(3.1.4) IISdietro un bilanciamento del carico non ha funzionato con altre soluzioni suggerite.

La lettura manuale X-Forwarded-Fordell'intestazione lo fa.

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

Sto eseguendo un pacchetto autonomo utilizzando il pacchetto di hosting .


0

Eseguendo ASP.NET Core 2.1 dietro un proxy inverso Traefik su Ubuntu, ho bisogno di impostare il suo IP gateway KnownProxiesdopo aver installato il Microsoft.AspNetCore.HttpOverridespacchetto ufficiale

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

Secondo la documentazione , ciò è necessario se il proxy inverso non è in esecuzione su localhost. Il docker-compose.ymldi Traefik ha assegnato un indirizzo IP statico:

networks:
  my-docker-network:
    ipv4_address: 192.168.3.2

In alternativa, dovrebbe essere sufficiente assicurarsi che qui sia definita una rete nota per specificare il suo gateway in .NET Core.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.