9 Replies Latest reply: Dec 13, 2012 3:46 PM by karthik chopperla RSS

    ATG Rest Services - capture IP of caller

    boyd4715
      Is it possible to capture the IP address of who is calling a REST service?

      The reason I am asking is that we seem to be having a lot of the following errors in our log file:

      ERROR [RepositoryServlet??] Error code: 500 CONTAINER:atg.repository.RepositorySecurityException; SOURCE:atg.security.PermissionDeniedException: You do not have read access to the category item descriptor.
      null
      atg.rest.RestException??: CONTAINER:atg.repository.RepositorySecurityException; SOURCE:atg.security.PermissionDeniedException: You do not have read access to the category item des criptor.

      Now, We have a mobile site which makes use of the REST services and they are all set up with the correct login/security.

      What I am trying to determine is who else is making these REST calls - something internal - or some unkown entity outside the application. I figured that if I can capture the IP then that will narrow down things. If it is outside, then the system is operating as expected and the error is justified. But if it is internal then need to do a bit more digging of what the root cause is.

      thanks
        • 1. Re: ATG Rest Services - capture IP of caller
          Gautam Singh
          REST request are like any HTTPS request and are processed by ATG request processing pipeline servlets. Add a request pipeline servlet or a servlet filter which can log the IP address.
          Here's sudo code for the same
          if ( "rest".equalsIgnoreCase(request.getContextPath()))
          {
          if( isLoggingInfo() )
          {
          logInfo("Request coming from " + request.getRemoteHost());
          }
          }
          • 2. Re: ATG Rest Services - capture IP of caller
            Gopinath Ramasamy
            Hi,

            In case you are using a web server, you may end up in getting the IP address of your own web server as client's IP.

            In that case, use the below code to get the actual IP of the client.

            String clientAddressStr = pRequest.getHeader("x-forwarded-for");
            if (clientAddressStr != null)
            {
                 // clientAddressStr will be of format : clientIP, Proxy1, Proxy2
                 String[] clientAddressArr = clientAddressStr.split(",");
                 logDebug("IP address is :: " + clientAddressArr[0].trim);
            }

            Thanks,
            Gopinath Ramasamy
            • 3. Re: ATG Rest Services - capture IP of caller
              boyd4715
              Well I seem to be stumped here and need some further guidance.

              First I created a servlet that extends InsertableServletImpl looking for the context path of rest.  I set it up with the following:  insertAfterServlet=/atg/dynamo/servlet/pipeline/DynamoServlet

              But, if I put in a rest call via a browser or from a unit test class, nothing happens.

              I then went, using the same servlet class extends GenericServletService (replacing InsertableServletImpl).  I then modified web.xml.  Ran the same test and again nothing happens.

              Based on the comments supplied one or both of these should of worked.

              Looking for some clarification, if at all possible, as to what I am doing incorrect here.

              The issue was simple that I was not putting it into the correct chain.  Needed to use the following:

              insertAfterServlet=/atg/dynamo/servlet/dafpipeline/ProtocolSwitchServlet

              Edited by: boyd4715 on Dec 13, 2012 8:05 AM

              Edited by: boyd4715 on Dec 13, 2012 8:06 AM
              • 4. Re: ATG Rest Services - capture IP of caller
                boyd4715
                Still having issues with capturing the IP of the REST client.
                • 5. Re: ATG Rest Services - capture IP of caller
                  boyd4715
                  I added the following to my method:

                                 if ("/rest".equalsIgnoreCase(pRequest.getContextPath()))
                                 {
                                      String clientAddressStr = pRequest.getHeader("x-forwarded-for");
                                      if (StringUtils.isNotBlank(clientAddressStr))
                                      {
                                           //clientAddressStr will be of format: clientIp, Proxy1, Proxy2
                                           String[] clientAddressArr = clientAddressStr.split(",");

                                           if (isLoggingInfo())
                                           {
                                                logInfo("service(DynamoHttpServletRequest, DynamoHttpServletResponse) - IP Address is:: " + clientAddressArr[0].trim()); //$NON-NLS-1$
                                           }
                                      }
                                 }

                  This does not work - the line

                  String clientAddressStr = pRequest.getHeader("x-forwarded-for");

                  always comes back as null.

                  Any issue of just grabbing the remote addr from the request?
                  • 6. Re: ATG Rest Services - capture IP of caller
                    Gautam Singh
                    try this
                    String clientAddressStr = request.getHeader("x-forwarded-for");
                    if (clientAddressStr == null || clientAddressStr.trim().equals("")) {
                    clientAddressStr = request.getHeader("X_FORWARDED_FOR");
                    if (clientAddressStr == null || clientAddressStr.trim().equals("")){
                    clientAddressStr = request.getRemoteAddr();
                    }
                    }
                    • 7. Re: ATG Rest Services - capture IP of caller
                      boyd4715
                      x-forwarded-for is no where to be found in the header. I printed out the header on the server and it is not there.
                      • 8. Re: ATG Rest Services - capture IP of caller
                        Gautam Singh
                        It's possible since the header is set by proxy servers and if the reequest is not through a proxy server you wont see this header.
                        That is why the last if statement gets the host by request.getRemoteAddr() call
                        • 9. Re: ATG Rest Services - capture IP of caller
                          karthik chopperla
                          request.getRemoteAddr() only gives the latest proxy addr.

                          X-forwarded-for value's left most address is the originating IP. Can you paste entire header here?

                          -karthik