Signaler

Comment obtenir l'@ IP des utilisateurs distants d'une Servlet? [Résolu]

Posez votre question chercheur2017 48Messages postés mardi 18 avril 2017Date d'inscription 4 juillet 2017 Dernière intervention - Dernière réponse le 4 juil. 2017 à 14:32 par chercheur2017
Bonjour à tous,

Dans le but de m'initier aux Servlts Java , j'ai créé une qui permet de faire de simple affichages. je l'ai testé sur le navigateur de ma machine et sur des navigateurs d'autres machines et ça marche bien.

J'ai besoin maintenant de connaitre les adresses IP (et les noms des machines) qui lancent ma servlet depuis leurs navigateurs. Y a -t-il un moyen de le faire?
j'ai essayé avec les instructions suivantes mais aucune ne me rend l'adresse attendue!!!

String hostName = null;
     try {
       final InetAddress addr = InetAddress.getLocalHost();
       hostName = new String(addr.getHostName());
     } catch(final Exception e) {
     }//end try
     out.println(hostName);
     
     
     out.print( request.getRemoteAddr() );
     out.print( request.getRemoteHost() );
     out.print( request.getHeader("x-forwarded-for") );


Merci de me proposer vos solutions.
Afficher la suite 
Utile
+0
plus moins
Bonjour,

On a déjà eu cette discussion il y a deux mois :
Comment obtenir l'@ IP d'un client de service web en Java?
InetAddress.getLocalHost()
c'est faux, ça va te renvoyer l'adresse IP de ton serveur, pas du client.

request.getHeader("X-FORWARDED-FOR");
est mieux, même s'il est à noter qu'il peut contenir plusieurs adresses IP, et que d'autres adresses IP peuvent se trouver dans d'autres headers.

J'ajouterais en plus :
1) les headers sont facultatifs donc rien ne garantie que les adresses IP soit effectivement présentes dans les headers
2) les headers peuvent être modifiés par le client ou n'importe quel élément réseau intermédiaire, donc sa valeur n'est pas fiable
3) on peut avoir plusieurs fois le même header avec des valeurs différentes
4) un header peut contenir une adresse IP mélangée avec d'autres informations (parfois d'autres adresses IP).

Le mieux serait donc d'aller regarder tous les headers et enregistrer tout ceux qui contiennent une adresse IP.
À ces résultats on rajoute ceux de getRemoteAddr() et getRemoteHost() qui sont à peu près les seuls que tu es sûr d'avoir bien que leur valeur ne représente rarement le client final mais plutôt le dernier élément réseau avec lequel tu discutes (un proxy par exemple).

public static void addIpAddress(String name, String header, Map<String, Set<String>> map) {
    if (name != null && header != null
            && header.matches("(\\p{Digit}+\\.){3}\\p{Digit}"
                    + "|(\\p{XDigit}+:){7}\\p{XDigit}+")) {
        Set<String> ips = map.get(name);
        if (ips == null) {
            ips = new TreeSet<>();
            map.put(name, ips);
        }
        ips.add(header);
    }
}

@SuppressWarnings("unchecked")
public static Map<String, Set<String>> parseIpHeaders(HttpServletRequest request) {
    Map<String, Set<String>> result = new TreeMap<>();
    Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
        String name = headerNames.nextElement();
        Enumeration<String> headerValues = request.getHeaders(name);
        while (headerValues.hasMoreElements()) {
            addIpAddress(name, headerValues.nextElement(), result);
        }
    }
    addIpAddress("REMOTE_ADDR", request.getRemoteAddr(), result);
    addIpAddress("REMOTE_HOST", request.getRemoteHost(), result);
    return result;
}
chercheur2017 48Messages postés mardi 18 avril 2017Date d'inscription 4 juillet 2017 Dernière intervention - 4 juil. 2017 à 13:04
Bonjour KX,

C'est bon, j'ai réglé le problème. La requête passait par un port intermédiaire qui ne renvoyait pas l'adresse voulue. J'ai changé de port et ça marche très bien. Mais, il me reste un petit problème concernant la fonction "getRemoteHost()" qui me retourne aussi l'adresse IP et pas le nom de la machine!!!

NB:
Concernant request.getHeader("X-FORWARDED-FOR"), alors cella elle me retourne une valeur "null"!!

Merci encore KX pour ta disponibilité.
Répondre
KX 14606Messages postés samedi 31 mai 2008Date d'inscription ModérateurStatut 21 juillet 2017 Dernière intervention - 4 juil. 2017 à 13:19
Une requête HTTP c'est juste un fichier texte que l'on envoie d'une machine à une autre. On met ce que l'on veut dedans et les éléments intermédiaires du réseau sont libres de le modifier.
Il y a juste un format normalisé qui permet d'en extraire des valeurs spéciales (les headers, les cookies...) mais c'est tout, sinon chacun fait ce qu'il veut.

request.getHeader("X-FORWARDED-FOR"), alors cella elle me retourne une valeur "null"
Voir ma remarque 1 : les header sont optionnels

"getRemoteHost()" qui me retourne aussi l'adresse IP et pas le nom de la machine
Voir ma remarque 2 : la valeur d'un header n'est pas fiable.

Remarque : il est toujours possible de filtrer les requêtes et refuser celles qui ne contiennent pas les valeurs que tu attends...
Répondre
chercheur2017 48Messages postés mardi 18 avril 2017Date d'inscription 4 juillet 2017 Dernière intervention - 4 juil. 2017 à 14:32
Ok, merci!!
Répondre
Donnez votre avis

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !