서블릿에서 클라이언트의 원격 주소를 어떻게 얻습니까?
서버로 들어오는 클라이언트의 원래 IP 주소를 얻을 수있는 방법이 있습니까? 나는 사용할 수 request.getRemoteAddr()
있지만 항상 프록시 또는 웹 서버의 IP를 얻는 것 같습니다.
클라이언트가 나에게 연결하는 데 사용하는 IP 주소를 알고 싶습니다. 어쨌든 내가 그것을 얻을 수 있습니까?
이 시도:
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()
방법입니다. 프록시가 소스 IP를 변경하는 것 같습니다. 일부 프록시는 일부 사용자 지정 http 헤더에 원래 IP를 추가합니다. 관심있는 항목이 없는지 확인하기 위해 모두 사용 request.getHeaderNames()
하고 request.getHeaders(name)
인쇄하십시오. 마치 X-CLIENT-IP
(그거 만들었지 만 이렇게 생겼어요)
내가 사용한 최고의 솔루션
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;
}
의미있는 방식으로이를 수행 할 수 없습니다.
프록시는 proxied-for 헤더를 추가 할 수도 있고 추가하지 않을 수도 있지만 대부분의 경우이 주소는 어쨌든 내부 전용 주소이므로 의미가 없습니다. 조직의 가장자리에있는 대부분의 프록시는 어쨌든 네트워크 내부에 대해 가능한 한 적게 드러내도록 구성됩니다.
이 정보를 어떤 용도로 사용 하시겠습니까?
이것은 일반적으로 응용 프로그램 문제가 아닌 배포 문제이므로 다른 접근 방식은 응용 프로그램 컨테이너를 적절하게 구성하는 것입니다. 일단 구성되면 컨테이너는 적절한 헤더를 검사하고 애플리케이션은 request.getRemoteAddr()
.
예를 들어 Tomcat에서는 원격 IP 밸브를 사용할 수 있습니다 . 대부분의 응용 프로그램 서버에는 비슷한 기능이 있다고 가정합니다.
컨테이너는 또한 프런트 엔드로드 밸런서가 SSL 연결을 종료하고 HTTP를 통해 요청을 앱 서버로 전달하는지 여부를 파악할 수 있습니다. 이는 애플리케이션이 자체에 대한 URL을 생성해야 할 때 중요합니다.
이와 같은 더 우아한 솔루션을 사용하지 않는 이유는 무엇입니까?
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) {
return IP_HEADERS.stream()
.map(request::getHeader)
.filter(Objects::nonNull)
.filter(ip -> !ip.isEmpty() && !ip.equalsIgnoreCase("unknown"))
.findFirst()
.orElseGet(request::getRemoteAddr);
}
코드를 중복 제거하십시오!
"x-forwarded-for"요청 헤더에는 프록시 또는로드 밸런서를 사용하는 경우 원래 클라이언트 IP가 포함됩니다. 그러나 모든 proxies / lb가이 헤더를 추가하는 것은 아니라고 생각합니다.
다음은 헤더를 구문 분석하는 자바 코드입니다. http://www.codereye.com/2010/01/get-real-ip-from-request-in-java.html
이 헤더가 없으면 @Bozho가 제안한대로 진행합니다.
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null) {
ipAddress = request.getHeader("X_FORWARDED_FOR");
if (ipAddress == null){
ipAddress = request.getRemoteAddr();
}
}
Why I think we should try to get IP from header 'X-Forwarded-For
' first? If you get from request.getRemoteAddr()
, it could be client's real ip or last proxy's ip which forwards the request. Thus we can't tell which condition it belongs to. However, if 'X-Forwarded-For
' is set into the header, client ip is bound to be the left-most part of what you get from it.
/**
* 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 "";
}
InetAddress inetAddress = InetAddress.getLocalHost();
String ip = inetAddress.getHostAddress();
참고URL : https://stackoverflow.com/questions/4678797/how-do-i-get-the-remote-address-of-a-client-in-servlet
'UFO ET IT' 카테고리의 다른 글
C # 폼에서 컨트롤의 위치 가져 오기 (0) | 2020.11.20 |
---|---|
uʍop-ǝpᴉsdn 텍스트는 어떻게 작동합니까? (0) | 2020.11.20 |
SQLite-SELECT TOP 구문 오류 (0) | 2020.11.20 |
내 PHP IDE가 종속성 주입 컨테이너를 이해하도록하려면 어떻게해야합니까? (0) | 2020.11.20 |
Char 배열을 문자열로 변환 (0) | 2020.11.20 |