web-dev-qa-db-fra.com

Comment obtenir l'adresse IP du client dans ASP.NET CORE?

Pouvez-vous s'il vous plaît laissez-moi savoir comment obtenir l'adresse IP du client dans ASP.NET lorsque vous utilisez MVC 6. Request.ServerVariables["REMOTE_ADDR"] ne fonctionne pas.

157
eadam

L'API a été mis à jour. Vous ne savez pas quand cela a changé, mais selon Damien Edwards fin décembre, vous pouvez maintenant le faire:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;
213
David Peden

Une logique de secours peut être ajoutée pour gérer la présence d’un Load Balancer.

En outre, lors de l'inspection, l'en-tête X-Forwarded-For est toujours défini, même sans équilibreur de charge (peut-être à cause d'une couche Kestrel supplémentaire?):

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

Suppose que _httpContextAccessor a été fourni par DI.

63
crokusek

Dans project.json, ajoutez une dépendance à:

"Microsoft.AspNetCore.HttpOverrides": "1.0.0"

Dans Startup.cs, dans la méthode Configure(), ajoutez:

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

Et bien sur:

using Microsoft.AspNetCore.HttpOverrides;

Ensuite, je pourrais obtenir l'adresse IP en utilisant:

Request.HttpContext.Connection.RemoteIpAddress

Dans mon cas, lors du débogage sous VS, je recevais toujours IpV6 localhost, mais une fois déployé sur un IIS, je recevais toujours l'adresse IP distante.

Quelques liens utiles: Comment obtenir l'adresse IP du client dans ASP.NET CORE? et RemoteIpAddress est toujours null

Le ::1 est peut-être à cause de:

Fin des connexions au niveau des services Internet (IIS), qui est ensuite transmise à Kestrel, le serveur Web v.next, afin que les connexions au serveur Web proviennent bien de localhost. ( https://stackoverflow.com/a/35442401/5326387 )

54
Johna

Vous pouvez utiliser le IHttpConnectionFeature pour obtenir cette information.

var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress;
16
Kiran Challa
var remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;
12
feradz

Dans ASP.NET 2.1, dans StartUp.cs, ajoutez ces services:

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

et ensuite faire 3 étapes:

  1. Définir une variable dans votre contrôleur MVC

    private IHttpContextAccessor _accessor;
    
  2. DI dans le constructeur du contrôleur

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

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()
    

Voici comment cela se fait.

5
hojjat.mi

Tout d'abord, dans .Net Core 1.0, ajoutez using Microsoft.AspNetCore.Http.Features; au contrôleur. Ensuite, dans la méthode appropriée:

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

J'ai lu plusieurs autres réponses qui ont échoué à la compilation car il utilisait un httpContext minuscule, ce qui a amené le VS à utiliser Microsoft.AspNetCore.Http au lieu de l'utilisation appropriée, ou avec HttpContext (le compilateur est également induit en erreur).

3
Guy

Dans mon cas, l’application Web DotNet Core 2.2 s’exécute sur DigitalOcean avec docker et nginx en tant que proxy inverse. Avec ce code dans Startup.cs, je peux obtenir l’IP du 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 était l'adresse IP que je devenais avant d'utiliser

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

Cela fonctionne pour moi (DotNetCore 2.1)

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