ASP.NET CORE에서 클라이언트 IP 주소는 어떻게 얻습니까?


206

MVC 6을 사용할 때 ASP.NET에서 클라이언트 IP 주소를 얻는 방법을 알려주십시오 Request.ServerVariables["REMOTE_ADDR"].


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

보류 이유는 질문의 맨 아래에 있습니다. "가능한 답변이 너무 많거나 좋은 답변이이 형식에 비해 너무 깁니다. 답변 세트를 좁히거나 답변 할 수있는 문제를 격리하려면 세부 정보를 추가하십시오. 몇 문단. "
케빈 브라운

12
나는 대답이 충분히 길지 않다고 생각합니다. 이전 버전의 MVC에서하는 일은 간단합니다. 방금 최신 베타 버전으로 작업하는 방법을 물었습니다. 둘째, 많은 답변이 있다면, 왜 아무도 그중 하나를 가리 키지 마십시오. 실제로 MVC 6은 베타 버전이므로 질문을 제대로 읽지 않았다고 생각합니다.
eadam

시도한 내용과 명확한 입력 / 출력을 보여주는 질문을 편집하십시오. 적어도 개선 하려고 노력 하지 않고 귀하의 질문이 종결되었다고 불평하지 마십시오 .

10
같은 도메인의 프로그래머 만이 문제를 해결해야합니다. asp.net 5.0에서 일하는 사람은 내가 무엇을 요구하는지 간단히 알 수 있습니다. 여러분 중 나머지는 간단한 질문을 게시 한 것에 대해 저를 처벌하고 있습니다.
eadam

답변:


276

API가 업데이트되었습니다. 언제 바뀌 었는지 확실하지 않지만 12 월 말 에 Damien Edwards따르면 다음 과 같이 할 수 있습니다.

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;

9
RemoteIpAddress항상 null내가 IIS에 자신의 웹 사이트를 게시하고 파일에이 로그인 할 때, 나를 위해.
A-Sharabiani

3
문제가 rc 2
Jon

12
원격으로 연결하더라도 항상 127.0.0.1을받습니다.
frostymarvelous

33
이것은 IPv6 형식 인 ":: 1"을 반환합니다. 다른 사람들은 127.0.0.1을 어떻게보고 있습니까?
Derek Greer

4
다른 사람이 IIS 서버의 로컬 IP 주소를 반환합니까?
dave317 April

73

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 웹 서버 인 Kestrel로 전달되므로 웹 서버에 대한 연결은 실제로 localhost에서 이루어집니다. ( https://stackoverflow.com/a/35442401/5326387 )


6
정답입니다. 리버스 프록시에 대한 공식 문서에도 나와 있습니다. docs.microsoft.com/en-us/aspnet/core/host-and-deploy/…
Melvyn

8
app.UseAuthentication () 전에 "app.UseForwardedHeaders ..."를 추가해야한다는 점을 지적해야합니다.
들여 쓰기

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

AspNetCore는 X-Forwarded-For와 같은 헤더로 RemoteIpAddress 속성을 재정의 할 수 있기 때문에 @feu 종류입니다.
Mark Lopez

@crokusek ... 솔루션을 조정하려고하지만 VS는이 코드를 정적으로 캡슐화하는 클래스로 강제합니다. 이 코드가 웹 앱 프로젝트 또는 솔루션의 클래스 라이브러리에 있습니까?
dinotom

처음 2 개의 메소드는 __httpContextAccessor를 제공하는 (또는 적용) 인스턴스에 있어야합니다. 두 번째 2 개의 문자열 메서드는 별도의 정적 확장 클래스에서 가져 왔습니다.
crokusek

이것은 특히 앱이 Kestrel을 사용하고 Linux에서 Nginx와 함께 호스팅되는 경우에 좋은 솔루션입니다.
Timothy Macharia

16

IHttpConnectionFeature이 정보를 얻기 위해를 사용할 수 있습니다 .

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

답변 해주셔서 감사합니다!
eadam

2
Kestrel 호스팅에서 작동합니까? 내 데모에서는 httpContext.GetFeature<IHttpConnectionFeature>()항상 null.
Jerry Bian

2
이 문서에 따르면 @JerryBian : github.com/aspnet/Docs/blob/master/aspnet/fundamentals/… , IHttpConnectionFeature는 Kestrel (아직)에서 지원되지 않습니다.
qbik

@JerryBian 그것은 지금이다
David Peden

더 이상 사용되지 않아야합니다. @feradz 버전은 RC-1에서 작동합니다.
fiat

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

6
지나치게 복잡합니다. MVC는 이미 내부적으로 호출하여 아래에 넣습니다 HttpContext.Connection.RemoteIpAddress.
Fred

@Fred-RC-1에서 IIS에 대한 버전이 null을 반환합니다. IIS 및 Kestrel
fiat

7

이것은 나를 위해 작동합니다 (DotNetCore 2.1)

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

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.
Stian

::1IPv6의 localhost입니다. IPv4 상당127.0.0.1
Andy

3

제 경우에는 Docker와 nginx를 리버스 프록시로 사용하여 DigitalOcean에서 DotNet Core 2.2 웹 앱을 실행하고 있습니다. 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를 사용하여 추가합니다.


2

.net 코어에서 ipaddress 및 호스트 이름 가져 오기

이 코드를 컨트롤러에 넣으십시오

다음과 같이하세요:

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

설명서 에 따르면 리버스 프록시가 로컬 호스트에서 실행되고 있지 않은 경우에 필요합니다. 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.