ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

ASP.NET でクライアントの IP アドレスを取得する

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

以上です。