ASP.NET MVC や Web API で、クライアントの IP アドレスを取得する方法をまとめておきます。プロキシサーバーなどを経由して Web サーバーに接続された場合、HTTP ヘッダーの X-Forwarded-For から取得する必要があります。
ASP.NET MVC
サーバー環境変数から取得しているため、HTTP_X_FORWARDED_FOR がキーとなります。
#HomeController.cs public ActionResult Index() { var clientIp = ""; var xForwardedFor = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (String.IsNullOrEmpty(xForwardedFor) == false) { clientIp = xForwardedFor.Split(',').GetValue(0).ToString().Trim(); } else { clientIp = Request.UserHostAddress; } if (clientIp != "::1"/*localhost*/) { clientIp = clientIp.Split(':').GetValue(0).ToString().Trim(); } ViewBag.Message = clientIp; return View(); }
ASP.NET Web API
HTTP ヘッダーの X-Forwarded-For から取得します。OWIN を使っている場合は、MS_HttpContext ではなく、MS_OwinContext の RemoteIpAddress から取得します。
#ValuesController.cs public string Get() { IEnumerable<string> headerValues; var clientIp = ""; if (ControllerContext.Request.Headers.TryGetValues("X-Forwarded-For", out headerValues) == true) { var xForwardedFor = headerValues.FirstOrDefault(); clientIp = xForwardedFor.Split(',').GetValue(0).ToString().Trim(); } else { if (ControllerContext.Request.Properties.ContainsKey("MS_HttpContext")) { clientIp = ((HttpContextWrapper)ControllerContext.Request.Properties["MS_HttpContext"]).Request.UserHostAddress; } } if (clientIp != "::1"/*localhost*/) { clientIp = clientIp.Split(':').GetValue(0).ToString().Trim(); } return clientIp; }
WCF
おまけです。WCF の場合は、HttpRequestMessageProperty から HTTP ヘッダーの情報を取得できます。
#Service1.svc.cs public string GetData(int value) { var clientIp = ""; var properties = OperationContext.Current.IncomingMessageProperties; var httpRequestMessage = properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; if (httpRequestMessage.Headers["X-Forwarded-For"] != null) { var xForwardedFor = httpRequestMessage.Headers["X-Forwarded-For"]; clientIp = xForwardedFor.Split(',').GetValue(0).ToString().Trim(); } else { var remoteEndpointMessage = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; clientIp = remoteEndpointMessage.Address; } if (clientIp != "::1"/*localhost*/) { clientIp = clientIp.Split(':').GetValue(0).ToString().Trim(); } return clientIp; }
以上です。