Saltar al contenido

¿Cómo puedo obtener la dirección IP del cliente en ASP.NET MVC?

Te doy la bienvenida a nuestro sitio web, ahora vas a encontrar la resolución que buscabas.

Solución:

La respuesta simple es usar la propiedad HttpRequest.UserHostAddress.

Ejemplo: Desde dentro de un controlador:

using System;
using System.Web.Mvc;

namespace Mvc.Controllers

    public class HomeController : ClientController
    
        public ActionResult Index()
        
            string ip = Request.UserHostAddress;

            ...
        
    

Ejemplo: Desde dentro de una clase de ayuda:

using System.Web;

namespace Mvc.Helpers

    public static class HelperClass
    
        public static string GetIPHelper()
        
            string ip = HttpContext.Current.Request.UserHostAddress;
            ..
        
    

PERO, Si la solicitud ha sido transmitida por uno o más servidores proxy, la dirección IP devuelta por la propiedad HttpRequest.UserHostAddress será la dirección IP del último servidor proxy que transmitió la solicitud.

Servidores proxy MAYO utilizar el de facto estándar de colocar la dirección IP del cliente en el encabezado HTTP X-Fordered-For. Aparte de que no hay garantía de que una solicitud tenga un encabezado X-Reenviado-For, tampoco hay garantía de que el X-Reenviado-For no haya sido SPOOFED.


Respuesta original

Request.UserHostAddress

El código anterior proporciona la dirección IP del Cliente sin tener que buscar una colección. La propiedad Solicitar está disponible en Controladores (o Vistas). Por lo tanto, en lugar de pasar una clase Page a su función, puede pasar un objeto Request para obtener el mismo resultado:

public static string getIPAddress(HttpRequestBase request)

    string szRemoteAddr = request.UserHostAddress;
    string szXForwardedFor = request.ServerVariables["X_FORWARDED_FOR"];
    string szIP = "";

    if (szXForwardedFor == null)
    
        szIP = szRemoteAddr;
    
    else
    
        szIP = szXForwardedFor;
        if (szIP.IndexOf(",") > 0)
        
            string [] arIPs = szIP.Split(',');

            foreach (string item in arIPs)
            
                if (!isPrivateIP(item))
                
                    return item;
                
            
        
    
    return szIP;

Request.ServerVariables["REMOTE_ADDR"] debería funcionar, ya sea directamente en una vista o en el cuerpo del método de acción del controlador (Request es una propiedad de la clase Controller en MVC, no en la página).

Está funcionando … pero tienes que publicar en un IIS real, no en el virtual.

Mucho del código aquí fue muy útil, pero lo limpié para mis propósitos y agregué algunas pruebas. Esto es lo que terminé con:

using System;
using System.Linq;
using System.Net;
using System.Web;

public class RequestHelpers

    public static string GetClientIpAddress(HttpRequestBase request)
    
        try
        
            var userHostAddress = request.UserHostAddress;

            // Attempt to parse.  If it fails, we catch below and return "0.0.0.0"
            // Could use TryParse instead, but I wanted to catch all exceptions
            IPAddress.Parse(userHostAddress);

            var xForwardedFor = request.ServerVariables["X_FORWARDED_FOR"];

            if (string.IsNullOrEmpty(xForwardedFor))
                return userHostAddress;

            // Get a list of public ip addresses in the X_FORWARDED_FOR variable
            var publicForwardingIps = xForwardedFor.Split(',').Where(ip => !IsPrivateIpAddress(ip)).ToList();

            // If we found any, return the last one, otherwise return the user host address
            return publicForwardingIps.Any() ? publicForwardingIps.Last() : userHostAddress;
        
        catch (Exception)
        
            // Always return all zeroes for any failure (my calling code expects it)
            return "0.0.0.0";
        
    

    private static bool IsPrivateIpAddress(string ipAddress)
    
        // http://en.wikipedia.org/wiki/Private_network
        // Private IP Addresses are: 
        //  24-bit block: 10.0.0.0 through 10.255.255.255
        //  20-bit block: 172.16.0.0 through 172.31.255.255
        //  16-bit block: 192.168.0.0 through 192.168.255.255
        //  Link-local addresses: 169.254.0.0 through 169.254.255.255 (http://en.wikipedia.org/wiki/Link-local_address)

        var ip = IPAddress.Parse(ipAddress);
        var octets = ip.GetAddressBytes();

        var is24BitBlock = octets[0] == 10;
        if (is24BitBlock) return true; // Return to prevent further processing

        var is20BitBlock = octets[0] == 172 && octets[1] >= 16 && octets[1] <= 31;
        if (is20BitBlock) return true; // Return to prevent further processing

        var is16BitBlock = octets[0] == 192 && octets[1] == 168;
        if (is16BitBlock) return true; // Return to prevent further processing

        var isLinkLocalAddress = octets[0] == 169 && octets[1] == 254;
        return isLinkLocalAddress;
    

Y aquí hay algunas pruebas de NUnit contra ese código (estoy usando Rhino Mocks para simular HttpRequestBase, que es el M llamar a continuación):

using System.Web;
using NUnit.Framework;
using Rhino.Mocks;
using Should;

[TestFixture]
public class HelpersTests : TestBase

    HttpRequestBase _httpRequest;

    private const string XForwardedFor = "X_FORWARDED_FOR";
    private const string MalformedIpAddress = "MALFORMED";
    private const string DefaultIpAddress = "0.0.0.0";
    private const string GoogleIpAddress = "74.125.224.224";
    private const string MicrosoftIpAddress = "65.55.58.201";
    private const string Private24Bit = "10.0.0.0";
    private const string Private20Bit = "172.16.0.0";
    private const string Private16Bit = "192.168.0.0";
    private const string PrivateLinkLocal = "169.254.0.0";

    [SetUp]
    public void Setup()
    
        _httpRequest = M();
    

    [TearDown]
    public void Teardown()
    
        _httpRequest = null;
    

    [Test]
    public void PublicIpAndNullXForwardedFor_Returns_CorrectIp()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(null);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(GoogleIpAddress);
    

    [Test]
    public void PublicIpAndEmptyXForwardedFor_Returns_CorrectIp()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(string.Empty);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(GoogleIpAddress);
    

    [Test]
    public void MalformedUserHostAddress_Returns_DefaultIpAddress()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(MalformedIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(null);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(DefaultIpAddress);
    

    [Test]
    public void MalformedXForwardedFor_Returns_DefaultIpAddress()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(MalformedIpAddress);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(DefaultIpAddress);
    

    [Test]
    public void SingleValidPublicXForwardedFor_Returns_XForwardedFor()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(MicrosoftIpAddress);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(MicrosoftIpAddress);
    

    [Test]
    public void MultipleValidPublicXForwardedFor_Returns_LastXForwardedFor()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(GoogleIpAddress + "," + MicrosoftIpAddress);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(MicrosoftIpAddress);
    

    [Test]
    public void SinglePrivateXForwardedFor_Returns_UserHostAddress()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(Private24Bit);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(GoogleIpAddress);
    

    [Test]
    public void MultiplePrivateXForwardedFor_Returns_UserHostAddress()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        const string privateIpList = Private24Bit + "," + Private20Bit + "," + Private16Bit + "," + PrivateLinkLocal;
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(privateIpList);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(GoogleIpAddress);
    

    [Test]
    public void MultiplePublicXForwardedForWithPrivateLast_Returns_LastPublic()
    
        // Arrange
        _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress);
        const string privateIpList = Private24Bit + "," + Private20Bit + "," + MicrosoftIpAddress + "," + PrivateLinkLocal;
        _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(privateIpList);

        // Act
        var ip = RequestHelpers.GetClientIpAddress(_httpRequest);

        // Assert
        ip.ShouldEqual(MicrosoftIpAddress);
    

Si te gusta el tema, tienes la libertad de dejar un post acerca de qué le añadirías a esta división.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *