Menu

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

chercheur2017 55 Messages postés mardi 18 avril 2017Date d'inscription 18 octobre 2017 Dernière intervention - 3 juil. 2017 à 13:59 - Dernière réponse : chercheur2017 55 Messages postés mardi 18 avril 2017Date d'inscription 18 octobre 2017 Dernière intervention
- 4 juil. 2017 à 14:32
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 

4 réponses

Répondre au sujet
KX 15225 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 février 2018 Dernière intervention - 3 juil. 2017 à 20:21
0
Utile
3
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 55 Messages postés mardi 18 avril 2017Date d'inscription 18 octobre 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é.
KX 15225 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 février 2018 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...
chercheur2017 55 Messages postés mardi 18 avril 2017Date d'inscription 18 octobre 2017 Dernière intervention > KX 15225 Messages postés samedi 31 mai 2008Date d'inscriptionModérateurStatut 18 février 2018 Dernière intervention - 4 juil. 2017 à 14:32
Ok, merci!!
Commenter la réponse de KX