Link to home
Start Free TrialLog in
Avatar of ablazso
ablazso

asked on

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

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?
ASKER CERTIFIED SOLUTION
Avatar of dualsoul
dualsoul

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ablazso
ablazso

ASKER

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?
Avatar of ablazso

ASKER

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>
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.
Avatar of ablazso

ASKER

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>
so is your client connects to port 80 or 8080, can you get your client connect to port 8080 directly and bypass apache server?
Avatar of ablazso

ASKER

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!
Avatar of ablazso

ASKER

F.Y.I, I pasted ':8080' to every location possible in the test program's URL, however it always fails to connect.
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.
Avatar of ablazso

ASKER

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?
Avatar of ablazso

ASKER

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.
>> 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.
Avatar of ablazso

ASKER

How do I go about puting mod.jk2 into Apache?  Is there some write-up on this?
Avatar of ablazso

ASKER

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.

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!
Avatar of ablazso

ASKER

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
Glad to know your problem is solved! It's always my pleasure to help :)
Thank you for remembering albazo :)