ASP.NET COREでクライアントIPアドレスを取得するにはどうすればよいですか?


202

MVC 6を使用Request.ServerVariables["REMOTE_ADDR"]できない場合にASP.NETでクライアントIPアドレスを取得する方法を教えてください。


例:httpContext.GetFeature<IHttpConnectionFeature>().RemoteIpAddress
キランチャラ2015

保留の理由は、質問の下部に表示されます。「可能な回答が多すぎるか、この形式では適切な回答が長すぎる可能性があります。回答セットを絞り込むか、回答可能な問題を特定するには、詳細を追加してください。数段落。」
ケビンブラウン

12
答えは十分に長いとは思いません。古いバージョンのMVCで行うのは簡単です。私はちょうど最新のベータ版でそれを行う方法を尋ねました。第二に、多くの答えがある場合、なぜ誰も私にそれらの1つを指摘しないでください。事実、MVC 6はベータ版であり、質問を読む前に正しく読んでいなかったと思います。
eadam

あなたが試したことの詳細と明確な入力/出力を示す質問を編集してください。少なくともそれを改善しようとせずにあなたの質問が閉じられたと文句を言うだけではありません。

10
同じドメインのプログラマーのみが質問を閉じる必要があります。asp.net 5.0で作業している人は、私が何を求めているのかをほんの一瞬で知るだけです。残りの皆さんは、単純な質問を投稿しただけで私を罰しているだけです。
eadam

回答:


271

APIが更新されました。いつ変更されたかはわかりませんが、12月下旬のDamien Edwards氏よると、次のようにしてください。

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;

9
IISで彼のWebサイトを公開し、これをファイルに記録するとき、これRemoteIpAddressは常にnull私にとってあります。
A-Sharabiani

3
問題はrc 2で修正されたようです
Jon

12
リモートで接続している場合でも、常に127.0.0.1を取得します
frostymarvelous

32
これは、IPv6形式である ":: 1"を返します。他の人は127.0.0.1をどのように見ていますか?
Derek Greer

4
他の誰かがIISサーバーのローカルIPアドレスを返しますか?
dave317 2018

72

project.jsonで、依存関係を以下に追加します。

"Microsoft.AspNetCore.HttpOverrides": "1.0.0"

ではStartup.csでは、Configure()メソッドの追加:

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

そしてもちろん:

using Microsoft.AspNetCore.HttpOverrides;

次に、次のコマンドを使用してIPを取得できます。

Request.HttpContext.Connection.RemoteIpAddress

私の場合、VSでデバッグするときは常にIpV6 localhostを取得しましたが、IISに展開するときは常にリモートIPを取得しました。

いくつかの便利なリンク: ASP.NET COREでクライアントIPアドレスを取得するにはどうすればよいですか?およびRemoteIpAddressは常にnullです

これ::1はおそらく次の理由によるものです:

IISで接続が終了すると、v.next WebサーバーであるKestrelに転送されるため、Webサーバーへの接続は実際にlocalhostから行われます。(https://stackoverflow.com/a/35442401/5326387


6
これは正解です。リバースプロキシに関する公式ドキュメントにも記載されています。docs.microsoft.com
Melvyn

8
「app.UseForwardedHeaders ...」はapp.UseAuthentication();の前に追加する必要があることを指摘する必要があります。ライン、インデントを使用する場合
netfed

1
これは完全に機能し、私はローカルでホストされているIISとAzureでテストしました。両方の場所で機能します。
ThomasCle

72

ロードバランサーの存在を処理するために、いくつかのフォールバックロジックを追加できます。

また、検査の結果、X-Forwarded-Forロードバランサーがなくてもヘッダーが設定されています(おそらく追加のKestrelレイヤーが原因である可能性があります)。

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

_httpContextAccessorDIを通じて提供されたと想定します。


2
これが正解です。特にアプリがNginx、ロードバランサーなどの背後にある場合、IPアドレスを取得する単一の方法はありません。ありがとう!
FEU

@feuは、AspNetCoreがRemoteIpAddressプロパティをX-Forwarded-Forのようなヘッダーでオーバーライドできるためです。
マークロペス

@crokusek ...あなたのソリューションを適応させようとしていますが、VSはこのコードを静的にカプセル化しているクラスに私を強制しています。このコードは、Webアプリプロジェクトまたはソリューションのクラスライブラリにありますか?
dinotom

最初の2つのメソッドは、__ httpContextAccessorを提供する(またはそれを適応させる)インスタンス内にある必要があります。2番目の2つの文字列メソッドは、別の静的拡張クラスから取得されました。
crokusek

これは、特にアプリがKestrelを使用し、LinuxのNginxでホストされている場合に適切なソリューションです。
Timothy Macharia、

16

IHttpConnectionFeatureこの情報を取得するためにを使用できます。

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

答えてくれてありがとう!
eadam 2015年

2
Kestrelホスティングで機能しますか?私のデモでは、httpContext.GetFeature<IHttpConnectionFeature>()常にになりますnull
ジェリービアン

2
このドキュメントによると@JerryBian:github.com/aspnet/Docs/blob/master/aspnet/fundamentals/…、IHttpConnectionFeatureは(まだ)Kestrelではサポートされていません。
qbik 2015年

@JerryBianそれが今です
David Peden

廃止されている必要があります- @feradzバージョンがRC-1で私の作品
フィアット

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

6
複雑すぎる。MVCは、すでにその内部と下プットそれを呼び出しますHttpContext.Connection.RemoteIpAddress
フレッド

@Fred-RC-1でバージョンがnullを返します-IISとKestrel
フィアット

7

ASP.NET 2.1では、StartUp.csでこのサービスを追加します。

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

次に、3つのステップを実行します。

  1. MVCコントローラーで変数を定義する

    private IHttpContextAccessor _accessor;
  2. コントローラーのコンストラクターへのDI

    public SomeController(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
  3. IPアドレスを取得する

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()

これがその方法です。


2
これは私に:: 1を与えます。Asp.Net Core 2.2。、localhost。
スティアン

::1IPv6ではlocalhostです。IPv4に相当するもの127.0.0.1
アンディ

6

これは私のために動作します(DotNetCore 2.1)

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

3

私のケースでは、DockNetとnginxをリバースプロキシとしてDigitalOceanでDotNet Core 2.2 Webアプリを実行しています。Startup.csのこのコードを使用して、クライアントIPを取得できます

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は、使用する前に取得していたIPでした

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

2

まず、.Net Core 1.0でusing Microsoft.AspNetCore.Http.Features;コントローラーに追加し、次に関連するメソッド内に追加します。

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

小文字のhttpContextを使用していたためにコンパイルに失敗した他のいくつかの回答を読んだため、VSは適切な使用の代わりに、またはHttpContextを使用して、Microsoft.AspNetCore.Httpを使用して追加しました(コンパイラも誤解を招きます)。


2

.netコアでIPアドレスとホスト名を取得する

このコードをコントローラーに入れます

次の手順を実行します:

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

2

私が見つけた、あなたの一部はあなたが得るIPアドレスが::: 1または0.0.0.1であることを見つけました

これは、自分のマシンからIPを取得しようとすることと、IPv6を返そうとするC#の混乱のために問題になります。

そこで、@ Johna(https://stackoverflow.com/a/41335701/812720)と@David(https://stackoverflow.com/a/8597351/812720)からの回答を実装しました。

そしてここで解決策:

  1. 参照(依存関係/パッケージ)にMicrosoft.AspNetCore.HttpOverridesパッケージを追加する

  2. この行を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. IPAddressを取得するには、任意の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();
    }

そして今、あなたはremoteIpAddressまたは結果からIPv4アドレスを得ることができます


1

これを試して。

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

0

ロードバランサーの背後で.NET core(3.1.4)を実行するIISと、他の推奨ソリューションでは機能しませんでした。

X-Forwarded-Forヘッダーを手動で読み取ることはできます。

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

ホスティングバンドルを使用して自己完結型パッケージを実行してます。


0

UbuntuでTraefikリバースプロキシの背後でASP.NET Core 2.1を実行しています。KnownProxies公式Microsoft.AspNetCore.HttpOverridesパッケージをインストールした後、ゲートウェイIPを設定する必要があります

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

ドキュメントによると、これはリバースプロキシがlocalhostで実行されていない場合に必要です。docker-compose.ymlTraefikのは、静的IPアドレスを割り当てています:

networks:
  my-docker-network:
    ipv4_address: 192.168.3.2

または、既知のネットワークが.NET Coreでゲートウェイを指定するためにここで定義されていることを確認するのに十分なはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.