Solved

How can I get a remote client's IP address within my JSP server side program?

Posted on 2003-11-07
21
4,274 Views
Last Modified: 2007-12-19
I have a client JSP that invokes a server base JSP to do something. It works flawlessly, as long as I don't care who is accessing it. But now, I would like to build into the server side JSP a feature that will restrict the usage to only a few IP numbers we trust. Unfortunately it is not as easy as I thought it would be.
I am trying to use getremoteaddr(), however it always returns 127.0.0.1 as the remote user's IP address, which is obviously incorrect.
Can anyone tell me how I can get the real IP of a remote user?
0
Comment
Question by:ablazso
  • 10
  • 8
  • 2
  • +1
21 Comments
 
LVL 15

Accepted Solution

by:
dualsoul earned 50 total points
ID: 9706393
hm...request.getRemoteAddr() - returns ip of remote client, who send the http request.
if it returns 127.0.0.1 - may be you've tested it on your local machine? i've never have problems with it.

you can try also: request.getRemoteHost(); - it will return domain name of client.
0
 
LVL 14

Assisted Solution

by:kennethxu
kennethxu earned 400 total points
ID: 9707153
it's mostly likely you are use a web server like Apache or IIS in front of your app server. If you use web server, both Apache and IIS can be easily configured that only certain ip can access the site.

let us know more detail of your setup and we might be able to help you better.
0
 
LVL 3

Assisted Solution

by:applekanna
applekanna earned 50 total points
ID: 9708593
In case you want to set you server as kennethxu suggested and your server is Apache

http://httpd.apache.org/docs-2.0/ssl/ssl_howto.html

and kennethxu u r back from a vaction ... so soon :) GOOD!
0
 

Author Comment

by:ablazso
ID: 9717576
Well, I do not want to configure Apache to accept only certain IPs. I would like to set Apache to pass through the remote client’s IPs unaltered!  My server based JSP will decide who should have access!  Besides, it will also have to look up some additional data, based on the remote users IP in a MySql database.

It seams to me that because Apache is the one that really connects to my server base JSP that is why I am always getting  it’s IP, 127.0.0.1, as the remote user's IP.
If it is true, can you suggest a way to remedy this problem?
0
 

Author Comment

by:ablazso
ID: 9719209
Gentlemen,

Below is the abbreviated version of the server side JSP that does not return the correct remote client's IP!
The original client's IP must have been  removed by either Apache or Tomcat and replaced and then replaced with 127.0.0.1.  In the program below replaced the URL (to protect the innocent). If it were not for the wrong remote IP, the program would work correctly, as it truely dows without the IP test.

Server's opsys is Red Hat 8.8 Apache's version is 2.0.4.0 and Tom Cats' version is 4.1.  Both Apache and Tom Cat are plain vanilla installations.

---------------------------------------------------------------------------------------------
<%@ taglib uri="http://jakarta.apache.org/taglibs/io-1.0" prefix="io" %>
<%@ taglib prefix="xtags" uri="http://jakarta.apache.org/taglibs/xtags-1.0" %>
<%@ taglib uri="http://jsptags.com/tags/navigation/pager" prefix="pg" %>
<%@ taglib uri="http://jakarta.apache.org/taglibs/i18n-1.0" prefix="i18n" %>

<%@ page import="java.text.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%@ page import="org.apache.commons.lang.CharSetUtils" %>

<% System.out.println(" ");
   System.out.println("================== CardService ===================");
   String ipnumber = request.getRemoteAddr();
   System.out.println("=== Remote user's IP Number = [" + ipnumber + "]");

   InputStreamReader isr = new InputStreamReader(request.getInputStream());
   BufferedReader b = new BufferedReader(isr);
     
   String s;
   StringBuffer inbuffer = new StringBuffer();
      
   while ((s = b.readLine()) != null){
        System.out.println(s);
        inbuffer.append(s);
        }

   int ipoint = inbuffer.indexOf("<CBBRequest>") + 12;
   int iname1 = inbuffer.indexOf("<Name>") + 6;
   int iname2 = inbuffer.indexOf("</Name>");
   String inName = inbuffer.substring(iname1,iname2);
   System.out.println("=== command recieved=[" + inName + "]");
       
   String xxName = "GetCardList";
   if (inName.equals(xxName)) {
      System.out.println("=== This is a 'GetCardList' command - 'cad' tag is inserted!");
      int ipoint2 = inbuffer.indexOf("</Name>") + 7;
      String cad = "<ClientAssignedData>" + "East-Co-01" + "</ClientAssignedData>";
      inbuffer.insert(ipoint2,cad);
      }
   else {
      System.out.println("=== This is not a 'GetCarList' command - 'cad' tag is not inserted!");
      }

   inbuffer.insert(ipoint,"<Authentication><SignOnID>EastCo</SignOnID><Pass123>Password</Password></Authentication>");
   System.out.println("=== Modified inbuffer:");            
   System.out.println(inbuffer);      

   b.close();
   b = null;
      
   System.out.println("Done - XML data delivered to XYZ!");  
%>

<io:http url="https://cbbs.calnetbank.com/XYZService.asp" action="POST" input="true" output="true">
  <io:header name="Content-Type" value="text/xml"/>
  <io:body>
     <%=inbuffer%>
  </io:body>
</io:http>
0
 
LVL 14

Expert Comment

by:kennethxu
ID: 9719492
which port is your tomcat running on and how your app has been accessed? I mean the url, more detail will help us to better help you.
0
 

Author Comment

by:ablazso
ID: 9719721
Tomcat is on 8080 Apache is on 80, the default port.
Please find the client side test program below.
It just assembles a DOM XML document then invokes the server based program (above) by posting the document to the server based program's URL.
The server program will insert some more XML data, sends the document to the bank's server to be processed, then the bank returns the response in XML format, which will be sent back to the client as is.

------------------------------ client side .html test program -------------------------------------------------------

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>
XML data exchange
</title>
<script type="text/javascript">
/* dummy implementations for those browsers not having XML support */
function createXMLFromString (string) {
  alert('XML not implemented.');
  return null;
}

function serializeXML (xmlDocument) {
  alert('XML not implemented.');
  return '';
}

function postXML (url, xmlDocument) {
  alert('XML not implemented.');
  return null;
}
</script>
<script type="text/javascript; version=1.5">
function createXMLFromString (string) {
  var xmlParser, xmlDocument;
  try {
    xmlParser = new DOMParser();
    xmlDocument = xmlParser.parseFromString(string, 'text/xml');
    return xmlDocument;
  }
  catch (e) {
    alert("Can't create XML document.");
    return null;
  }
}

function serializeXML (xmlDocument) {
  var xmlSerializer;
  try {
    xmlSerializer = new XMLSerializer();
    return xmlSerializer.serializeToString(xmlDocument);
  }
  catch (e) {
    alert("Can't serialize XML document.");
    return '';
  }
}

function postXML (url, xmlDocument) {
  try {
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('POST', url, false);
    httpRequest.send(xmlDocument);
    return httpRequest;
  }
  catch (e) {
    alert("Can't post XML document");
    return null;
  }
}
</script>
<script type="text/jscript">
function createXMLFromString (string) {
  var xmlDocument;
  try {
    xmlDocument = new ActiveXObject('Msxml2.DOMDocument');
    xmlDocument.async = false;
    xmlDocument.loadXML(string);
    return xmlDocument;
  }
  catch (e) {
    alert("Can't create XML document.");
    return null;
  }
}

function serializeXML (xmlDocument) {
  return xmlDocument.xml;
}

function postXML (url, xmlDocument) {
  var httpRequest;
  try {
    httpRequest = new ActiveXObject('Msxml2.XMLHTTP');
    httpRequest.open('POST', url, false);
    httpRequest.send(xmlDocument);
    return httpRequest;
  }
  catch (e) {
    alert("Can't post XML document.");
    return null;
  }
}
</script>
<script type="text/javascript">
function appendToBody (text) {
  if (document.body && document.createTextNode) {
    document.body.appendChild(document.createTextNode(text));
    document.body.appendChild(document.createElement('br'));
  }
}
</script>
</head>
<body>
<script type="text/javascript">
var xmlDocument =
  createXMLFromString('<XYXRequest><Service ID=\"0\"><Type>Card Management</Type><Name>GetCardBalance</Name><PAN>5778072000111111</PAN></Service></XYZRequest>');
if (xmlDocument) {
  appendToBody('xmlDocument.documentElement.nodeName: ' +
xmlDocument.documentElement.nodeName);

  appendToBody('XML source: ' + serializeXML(xmlDocument));
  var httpRequest = postXML('http://sandbox.east1.net/services/CardService.jsp', xmlDocument);
  if (httpRequest) {
    appendToBody('response status: ' + httpRequest.status);
    appendToBody('response text: ' + httpRequest.responseText);
    appendToBody('_____________________ ');
    var xmlResponse = httpRequest.responseXML;
    appendToBody('response document.documentElement.nodeName: ' +
xmlResponse.documentElement.nodeName);
  }
}
</script>
</body>
</html>
0
 
LVL 14

Expert Comment

by:kennethxu
ID: 9719745
so is your client connects to port 80 or 8080, can you get your client connect to port 8080 directly and bypass apache server?
0
 

Author Comment

by:ablazso
ID: 9720186
As you can see I just connect to the URL normally. You think I should I do it differently to bypass Apache? If so who can it be done, given the above URL? The :8080 goes where? After the 'sandbox'?

Thank you so much for trying to help me!
0
 

Author Comment

by:ablazso
ID: 9720304
F.Y.I, I pasted ':8080' to every location possible in the test program's URL, however it always fails to connect.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 14

Expert Comment

by:kennethxu
ID: 9723542
can you try to access you page at:
http://sandbox.east1.net:8080/services/CardService.jsp

assuming you have tomcat running at port 8080 on sandbox.east1.net.
0
 

Author Comment

by:ablazso
ID: 9723844
Yes I did, but it was rejected by the server. Probably because the software fire-wall!
We use Apache on our servers, mostly because we are also using Red Hat's software fire-wall, but we are not using any cache mechanism or webcache as far as I know.
The 'locking out IP addresses' won't work in this case because, as I've mentioned, my server based program needs the remote client's IP to get more info form a MySql database before proceeding.

I will be at the server location around 4:00 PM PST, then I can answer in detail to any setup questions you think would help.

In the mean time I found under Web Development Topics, JSP Area ( by searching with keyword 'getremoteaddr') one question that I think may be pertinent to my problem. Will you please take a look at it and let me know if it is similar to my problem?
0
 

Author Comment

by:ablazso
ID: 9727436
I've heard that this has been a problem ever since Tomcat 3.3. Also, that if the server is using mod_rewrite.

What do you think of using mod.jk2?  Do you think mod.jk2 can make a difference, since it is Apache who is creating the calls that arrive to the Tomcat instance. Would not Tomcat always get the localhost parameter, no matter what? Just a thought.
0
 
LVL 14

Expert Comment

by:kennethxu
ID: 9728397
>> server is using mod_rewrite
I'm positive that this is the reason why you are getting localhost address, apache is actually acting as a reverse proxy server.

>> Do you think mod.jk2 can make a difference
I'm very positive on this!

another option if you are not using apache for something else, you can let tomcat directly run on port 80.
0
 

Author Comment

by:ablazso
ID: 9728966
How do I go about puting mod.jk2 into Apache?  Is there some write-up on this?
0
 
LVL 14

Expert Comment

by:kennethxu
ID: 9732562
0
 

Author Comment

by:ablazso
ID: 9733070
I found out today that we are using mod_proxy on the 'sandbox' server! This, I believe, does a simple proxy pass one way in and a proxy pass reverse out, which supposed to make all requests to our server go through Tomcat. I think this module makes all requests come from local host! Because 'sandbox' needs several upgrades anyway, (we would like to fully upgrade it to RH10/FC1 - it is currently RH8) we will try to install mod_j2k at the same time!

On another server, 'icebox', a year or so ago, our people tried to set up mod_jk2, but it never worked when it was installed, so they installed mod_jk instead.  I don't know what is the difference between mod_jk and ..jk2, but I intend to re-test my server based jsp program on this server today.

I am crossing my fingers.

0
 
LVL 14

Expert Comment

by:kennethxu
ID: 9733643
mod_jk2 is the updated version of mod_jk, jk work with apache 1.3 only but jk2 works with both 1.3 and 2.0

>>I am crossing my fingers.
bless you!
0
 

Author Comment

by:ablazso
ID: 9741078
We upgraded the system, reinstalled Apache, Java and Tomcat with mod_jk2, then did a few tests form different IP locations. It worked flawlessly!

Thanks for all your help!

Alex
0
 
LVL 14

Expert Comment

by:kennethxu
ID: 9741133
Glad to know your problem is solved! It's always my pleasure to help :)
0
 
LVL 3

Expert Comment

by:applekanna
ID: 9743267
Thank you for remembering albazo :)
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Is your Office 365 signature not working the way you want it to? Are signature updates taking up too much of your time? Let's run through the most common problems that an IT administrator can encounter when dealing with Office 365 email signatures.
What is Backup? Backup software creates one or more copies of the data on your digital devices in case your original data is lost or damaged. Different backup solutions protect different kinds of data and different combinations of devices. For e…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now