Existe-t-il un moyen d'obtenir l'adresse IP d'origine du client arrivant sur le serveur? Je peux utiliser request.getRemoteAddr()
, mais je semble toujours obtenir l'adresse IP du proxy ou du serveur Web.
Je voudrais connaître l'adresse IP que le client utilise pour se connecter à moi. Y at-il de toute façon que je pourrais l'obtenir?
essaye ça:
public static String getClientIpAddr(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
request.getRemoteAddr()
est le chemin. Il semble que votre proxy change l'adresse IP source. Lorsque certains mandataires le font, ils ajoutent l'adresse IP d'origine dans un en-tête http personnalisé. Utilisez request.getHeaderNames()
et request.getHeaders(name)
et imprimez-les tous pour voir s’il n’ya rien d’intéressant. Comme X-CLIENT-IP
(créé celui-là, mais ils ressemblent à ceci)
La meilleure solution que j'ai jamais utilisée
public String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
Vous ne pouvez pas le faire de manière significative.
Le mandataire peut ou non ajouter un en-tête pour le mandataire, mais dans de nombreux cas, il s'agira de toute façon d'une adresse interne, ce qui n'aura donc aucun sens pour vous. La plupart des serveurs proxy situés à la périphérie d'une organisation sont configurés de manière à révéler le moins possible les composants internes du réseau.
Pourquoi avez-vous l'intention d'utiliser ces informations?
Comme il s'agit généralement d'un problème de déploiement, plutôt que d'un problème d'application, une autre approche consiste à configurer le conteneur d'applications de manière appropriée. Une fois configuré, le conteneur se charge d'inspecter l'en-tête approprié et votre application continue à utiliser request.getRemoteAddr()
.
Par exemple, dans Tomcat, vous pouvez utiliser le Remote IP Valve . Je suppose que la plupart des serveurs d'applications ont des fonctionnalités similaires.
Le conteneur peut également s'occuper de comprendre si votre équilibreur de charge frontal met fin aux connexions SSL et transmet la demande au serveur d'applications via HTTP. Ceci est important lorsque votre application doit générer des URL vers elle-même.
L'en-tête de demande "x-forwarded-for" contient l'adresse IP du client d'origine si vous utilisez un proxy ou un équilibreur de charge. Mais je pense que tous les mandataires/lb n’ajoute pas cet en-tête.
Voici un peu de code Java pour analyser l’en-tête: http://www.codereye.com/2010/01/get-real-ip-from-request-in-Java.html
Si cet en-tête n'est pas présent, je procéderais comme le suggère @ Boho
Pourquoi ne pas utiliser une solution plus élégante comme celle-ci?
private static final List<String> IP_HEADERS = Arrays.asList("X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR");
public static String getClientIpAddr(HttpServletRequest request) {
for (String ipHeader : IP_HEADERS) {
String ip = request.getHeader(ipHeader);
if (ip != null && !ip.isEmpty() && !ip.equalsIgnoreCase("unknown")) {
return ip;
}
}
return request.getRemoteAddr();
}
Dédupliquez votre code!
Pourquoi je pense que nous devrions essayer d'obtenir d'abord l'adresse IP de l'en-tête 'X-Forwarded-For
'? Si vous obtenez de request.getRemoteAddr()
, il peut s’agir de de l’adresse IP réelle du client ou du dernier proxy qui transmet la demande . Ainsi, nous ne pouvons pas dire à quelle condition il appartient. Toutefois, si 'X-Forwarded-For
' est défini dans l'en-tête, l'adresse IP du client est vouée à être la partie la plus à gauche de ce que vous obtenez.
/**
* Try to get real ip from request:
* <ul>
* <li>try X-Forwarded-For</li>
* <li>try remote address</li>
* </ul>
*
* @param request request
* @return real ip or ""
*/
private String tryGetRealIp(HttpServletRequest request) {
// X-Forwarded-For: <client>, <proxy1>, <proxy2>
// If a request goes through multiple proxies, the IP addresses of each successive proxy is listed.
// This means, the right-most IP address is the IP address of the most recent proxy and
// the left-most IP address is the IP address of the originating client.
String forwards = request.getHeader("X-Forwarded-For");
if (StringUtils.isNotBlank(forwards)) {
// The left-most IP must be client ip
String ip = StringUtils.substringBefore(forwards, ",");
return ip;
} else if (StringUtils.isNotBlank(request.getRemoteAddr())) {
// this could be real client ip or last proxy ip which forwards the request
return request.getRemoteAddr();
}
return "";
}
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null) {
ipAddress = request.getHeader("X_FORWARDED_FOR");
if (ipAddress == null){
ipAddress = request.getRemoteAddr();
}
}