You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by myerscb <my...@upmc.edu> on 2011/06/10 16:37:06 UTC

Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Hi,

I am using CXF 2.4.0 in a Tomcat 7.0.14 container.

I have it set up to do both JAX-WS and JAX-RS.  I am using a beans.xml to
register the serivices:

beans.xml snippit:

     <jaxrs:server id="goldenKey_rest" address="/rest">
       <jaxrs:serviceBeans>
         <ref bean="goldenKey_bean" />
       </jaxrs:serviceBeans>
		<jaxrs:providers>
		  <ref bean="dateProvider" />
		  <ref bean="exceptionMapper" />
		</jaxrs:providers>
     </jaxrs:server>

      <jaxws:endpoint xmlns:s="http://com.upmc.tdc.server"
         serviceName="s:GoldenKey"
         endpointName="s:GoldenKeyPort"
         id="goldenKey_soap"
         implementor="#goldenKey_bean"
         address="/soap" />      

I am trying to capture the client ip address for both REST and SOAP.  It
works perfectly with REST but not SOAP.

here is the code that i am using to get the HttpServletReqeust object (this
is in my service implementation class):

	@Resource
	private HttpServletRequest request = null;

	@Resource
	public void setContext(WebServiceContext context) {
		if (context != null && context.getMessageContext() != null &&
context.getMessageContext().get(AbstractHTTPDestination.HTTP_REQUEST) !=
null) {
			this.request = (HttpServletRequest)
context.getMessageContext().get(AbstractHTTPDestination.HTTP_REQUEST);
		}
	}

As i said, REST works great.  But when i try to use SOAP the request object
returns null as soon as i do a getRemoteAddr().

The soap request it being submitted using Apache HttpClient.

here is some CXF output about the request:

INFO: Inbound Message
----------------------------
ID: 1
Address: http://localhost:8080/GoldenKey/svc/soap
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=utf-8
Headers: {connection=[Keep-Alive], Content-Length=[387],
content-type=[text/xml; charset=utf-8], host=[localhost:8080],
user-agent=[Apache-HttpClient/4.1 (java 1.5)], x-forwarded-for=[This is my
ip address: 127.0.0.1]}
Payload: <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAddressTypes
xmlns:ns2="http://com.upmc.tdc.server"><ns2:Application><applicationId>2a24907c-59c2-4415-b944-a5d1148544d1</applicationId></ns2:Application><ns2:User><username>myerscb</username></ns2:User><ns2:DataSourceType>EPCD</ns2:DataSourceType></ns2:getAddressTypes></soap:Body></soap:Envelope>
--------------------------------------

it certainly looks like the headers are there, even one that I inserted
(x-forwarded-for).  But, when I attempt to try and access the headers
through the request object, i get a null pointer exception.

I am wondering what i am missing?  is there a different way to get header
information for a soap request?

Thanks for your help,

Chris


--
View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p4476334.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by Ted <r6...@gmail.com>.
sorry I'm out of ideas, I use tomcat 7 / cxf 2.6.1 / oraclejdk 1.6 all on
fedora 16 x86_64, and it works for me so I'd say it might be something to
do with your setup but I don't have any more ideas off hand.

On Fri, Jun 15, 2012 at 7:47 AM, lashemale <la...@yahoo.fr> wrote:

> no proxy.
> my server is jonas, i tried also with tomcat.
> there's no proxy on my computer in front of jonas or tomcat
>
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p5709835.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>



-- 
Ted.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by lashemale <la...@yahoo.fr>.
no proxy.
my server is jonas, i tried also with tomcat.
there's no proxy on my computer in front of jonas or tomcat

--
View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p5709835.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by Ted <r6...@gmail.com>.
you sure it's not because of a proxy you have in place in front of it or
something?

On Thu, Jun 14, 2012 at 8:49 PM, lashemale <la...@yahoo.fr> wrote:

> I tried this before. Same result... I get the adress of the web service,
> not
> the adress of my client ;-(
>
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p5709745.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>



-- 
Ted.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by lashemale <la...@yahoo.fr>.
I tried this before. Same result... I get the adress of the web service, not
the adress of my client ;-(

--
View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p5709745.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by Ted <r6...@gmail.com>.
I can get the calling IP, but I do it from the In-Interceptor

        HttpServletRequest request = (HttpServletRequest)
message.get(AbstractHTTPDestination.HTTP_REQUEST);
        String ip = request.getRemoteAddr();

the above is what I use to get it.

On Wed, Jun 13, 2012 at 9:04 PM, lashemale <la...@yahoo.fr> wrote:

> Hello,
>
> I tried both solutions (i use only SOAP client).
> I try several times since 2 weeks, that never work, i have not the good
> adress.
> That gives me IP adress of the web service, not the IP adress of the SOAP
> client where i call the web service.
>
> I try getRemoteAddr(), getLocalAddr(), getLocalName(), etc.
>
> Before becoming mad, is anybody know why ? ;-)
>
> arnaud
>
>
>
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p5709659.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>



-- 
Ted.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by lashemale <la...@yahoo.fr>.
Hello,

I tried both solutions (i use only SOAP client).
I try several times since 2 weeks, that never work, i have not the good
adress.
That gives me IP adress of the web service, not the IP adress of the SOAP
client where i call the web service.

I try getRemoteAddr(), getLocalAddr(), getLocalName(), etc.

Before becoming mad, is anybody know why ? ;-)

arnaud



--
View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p5709659.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

Dan's solution definitely involves less code.
I guess using org.apache.cxf.jaxrs.ext.MessageContext offers a cheap
way of figuring out if it's a soap request which is in scope or not.
Setting a property  on the current message from say JAX-RS filter and
use PhaseInterceptorChain.getCurrentMessage().get(propertyName) will
do it too

Cheers, Sergey

On Mon, Jun 13, 2011 at 6:06 PM, myerscb <my...@upmc.edu> wrote:
> Hi,
>
> This time it really works!  thanks for all your help.
>
> with
>
>         @Resource org.apache.cxf.jaxrs.ext.MessageContext jaxrsContext;
>
>                if (jaxrsContext.getServletContext() == null) {
>                        request = (HttpServletRequest)
> jaxwsContext.getMesgeContext().get(MessageContext.SERVLET_REQUEST);
>                } else {
>                        request = (HttpServletRequest)
> jaxrsContext.get(AbstractHTTPDestination.HTTP_REQUEST);
>                }
>
> works as expected.
>
> Also HttpServletRequest request = (HttpServletRequest)
> PhaseInterceptorChain.getCurrentMessage().get("HTTP.REQUEST"); works as
> well.
>
> Is one solution better to use?  I would probably go with Dan's solution
> because there is less code.  But that may not be the better choice.
>
> Thanks again,
>
> Chris
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p4485072.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by myerscb <my...@upmc.edu>.
Hi,

This time it really works!  thanks for all your help.

with

	 @Resource org.apache.cxf.jaxrs.ext.MessageContext jaxrsContext;

		if (jaxrsContext.getServletContext() == null) {
			request = (HttpServletRequest)
jaxwsContext.getMessageContext().get(MessageContext.SERVLET_REQUEST);
		} else {
			request = (HttpServletRequest)
jaxrsContext.get(AbstractHTTPDestination.HTTP_REQUEST);
		}

works as expected.

Also HttpServletRequest request = (HttpServletRequest)
PhaseInterceptorChain.getCurrentMessage().get("HTTP.REQUEST"); works as
well.

Is one solution better to use?  I would probably go with Dan's solution
because there is less code.  But that may not be the better choice.

Thanks again,

Chris

--
View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p4485072.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by Daniel Kulp <dk...@apache.org>.
Honestly, in this case, it might be getter to just call:

PhaseInterceptorChain.getCurrentMessage()

and grab the HTTPRequest object out of there.  That would work with both JAX-
WS and JAXRS and avoids the mismatch of injections and such.  

It ties it to CXF API's, but that may not matter too much for you.


Dan


On Monday, June 13, 2011 6:52:07 AM myerscb wrote:
> it appears that I spoke to soon.
> 
> The jaxrsContext is null.  So when I attempt to get the ip address when
> running a REST query i get a null pointer.
> 
> What i have figured out is if i switch jaxrsContext to a
> org.apache.cxf.jaxrs.ext.MessgeContext from a
> javax.xml.ws.handler.MessageContext the rest side start to work.  But, the
> SOAP side no longer works (which it does if I use the
> javax.xml.ws.handler.MessageContext.
> 
> I am not sure why changing the package of the MessageContext for
> jaxrsContext affects the jaxwsContext but it does.
> 
> so to be clear i am including the relevant code again with package info.
> 
> 	 @Resource javax.xml.ws.WebServiceContext jaxwsContext;
> 	 @Resource javax.xml.ws.handler.MessageContext jaxrsContext;
> 
> 	private String getIpAddress() {
> 		String ipAddress = " unknown";
> 		javax.servlet.http.HttpServletRequest request = null;
> 
> 		if (jaxrsContext != null) {
> 			request = (HttpServletRequest)
> jaxrsContext.get(org.apache.cxf.transport.http.AbstractHTTPDestination.HTTP_
> REQUEST); } else if (jaxwsContext != null) {
> 			request = (HttpServletRequest)
> jaxwsContext.getMessageContext().get(javax.xml.ws.handler.MessageContext.SER
> VLET_REQUEST); } else {
> 			// TODO can not get ip address
> 			// should we through and exception
> 		}
> 
> 		if (request != null){
> 			if (StringUtils.isNotBlank(request.getHeader("X-Forwarded-
For"))) {
> 				ipAddress = request.getHeader("X-Forwarded-For");
> 			} else {
> 				ipAddress = request.getRemoteAddr();
> 			}
> 		}
> 
> 		// System.out.println("IP ADDRESS: " + ipAddress);
> 		return ipAddress;
> 	}
> 
> any help would be greatly appreciated.
> 
> Thanks,
> 
> Chris
> 
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-work
> s-for-REST-clients-but-not-for-SOAP-clients-tp4476334p4484400.html Sent from
> the cxf-user mailing list archive at Nabble.com.
-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Talend - http://www.talend.com

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by Sergey Beryozkin <sb...@gmail.com>.
Inject context are never set to null because they're proxies.
what you can do is this:
if (jaxrsContext.getServletContext() == null) {
// access jaxws context
} else {
   //access jaxrs servlet context
}

Cheers, Sergey

On Mon, Jun 13, 2011 at 2:52 PM, myerscb <my...@upmc.edu> wrote:
> it appears that I spoke to soon.
>
> The jaxrsContext is null.  So when I attempt to get the ip address when
> running a REST query i get a null pointer.
>
> What i have figured out is if i switch jaxrsContext to a
> org.apache.cxf.jaxrs.ext.MessgeContext from a
> javax.xml.ws.handler.MessageContext the rest side start to work.  But, the
> SOAP side no longer works (which it does if I use the
> javax.xml.ws.handler.MessageContext.
>
> I am not sure why changing the package of the MessageContext for
> jaxrsContext affects the jaxwsContext but it does.
>
> so to be clear i am including the relevant code again with package info.
>
>         @Resource javax.xml.ws.WebServiceContext jaxwsContext;
>         @Resource javax.xml.ws.handler.MessageContext jaxrsContext;
>
>        private String getIpAddress() {
>                String ipAddress = " unknown";
>                javax.servlet.http.HttpServletRequest request = null;
>
>                if (jaxrsContext != null) {
>                        request = (HttpServletRequest)
> jaxrsContext.get(org.apache.cxf.transport.http.AbstractHTTPDestination.HTTP_REQUEST);
>                } else if (jaxwsContext != null) {
>                        request = (HttpServletRequest)
> jaxwsContext.getMessageContext().get(javax.xml.ws.handler.MessageContext.SERVLET_REQUEST);
>                } else {
>                        // TODO can not get ip address
>                        // should we through and exception
>                }
>
>                if (request != null){
>                        if (StringUtils.isNotBlank(request.getHeader("X-Forwarded-For"))) {
>                                ipAddress = request.getHeader("X-Forwarded-For");
>                        } else {
>                                ipAddress = request.getRemoteAddr();
>                        }
>                }
>
>                // System.out.println("IP ADDRESS: " + ipAddress);
>                return ipAddress;
>        }
>
> any help would be greatly appreciated.
>
> Thanks,
>
> Chris
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p4484400.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by myerscb <my...@upmc.edu>.
it appears that I spoke to soon.

The jaxrsContext is null.  So when I attempt to get the ip address when
running a REST query i get a null pointer.

What i have figured out is if i switch jaxrsContext to a
org.apache.cxf.jaxrs.ext.MessgeContext from a
javax.xml.ws.handler.MessageContext the rest side start to work.  But, the
SOAP side no longer works (which it does if I use the
javax.xml.ws.handler.MessageContext.

I am not sure why changing the package of the MessageContext for
jaxrsContext affects the jaxwsContext but it does.

so to be clear i am including the relevant code again with package info.

	 @Resource javax.xml.ws.WebServiceContext jaxwsContext;
	 @Resource javax.xml.ws.handler.MessageContext jaxrsContext;

	private String getIpAddress() {
		String ipAddress = " unknown";
		javax.servlet.http.HttpServletRequest request = null;
		
		if (jaxrsContext != null) {
			request = (HttpServletRequest)
jaxrsContext.get(org.apache.cxf.transport.http.AbstractHTTPDestination.HTTP_REQUEST);
		} else if (jaxwsContext != null) {
			request = (HttpServletRequest)
jaxwsContext.getMessageContext().get(javax.xml.ws.handler.MessageContext.SERVLET_REQUEST);
		} else {
			// TODO can not get ip address
			// should we through and exception			
		}
		
		if (request != null){
			if (StringUtils.isNotBlank(request.getHeader("X-Forwarded-For"))) {
				ipAddress = request.getHeader("X-Forwarded-For");
			} else {
				ipAddress = request.getRemoteAddr();
			}
		}	

		// System.out.println("IP ADDRESS: " + ipAddress);
		return ipAddress;
	}

any help would be greatly appreciated.

Thanks,

Chris

--
View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p4484400.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by myerscb <my...@upmc.edu>.
Sergey,

thank you, that is exactly what i was looking for.

It is working correctly now.

here is what i did in my impl class:

	 @Resource WebServiceContext jaxwsContext;
	 @Resource MessageContext jaxrsContext;


and the method where i get the ip address:

	private String getIpAddress() {
		String ipAddress = " unknown";
		HttpServletRequest request = null;
		
		if (jaxrsContext != null) {
			request = (HttpServletRequest)
jaxrsContext.get(AbstractHTTPDestination.HTTP_REQUEST);
		} else if (jaxwsContext != null) {
			request = (HttpServletRequest)
jaxwsContext.getMessageContext().get(MessageContext.SERVLET_REQUEST);
		} else {
			// TODO can not get ip address
			// should we through and exception			
		}
		
		if (request != null){
			if (StringUtils.isNotBlank(request.getHeader("X-Forwarded-For"))) {
				ipAddress = request.getHeader("X-Forwarded-For");
			} else {
				ipAddress = request.getRemoteAddr();
			}
		}	

		// System.out.println("IP ADDRESS: " + ipAddress);
		return ipAddress;
	}

thanks again,

Chris

--
View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p4476721.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Getting the IP Address of SOAP Clients (works for REST clients but, not for SOAP clients)

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

>
> here is the code that i am using to get the HttpServletReqeust object (this
> is in my service implementation class):
>
>        @Resource
>        private HttpServletRequest request = null;
>
>        @Resource
>        public void setContext(WebServiceContext context) {
>                if (context != null && context.getMessageContext() != null &&
> context.getMessageContext().get(AbstractHTTPDestination.HTTP_REQUEST) !=
> null) {
>                        this.request = (HttpServletRequest)
> context.getMessageContext().get(AbstractHTTPDestination.HTTP_REQUEST);
>                }
>        }
>
> As i said, REST works great.  But when i try to use SOAP the request object
> returns null as soon as i do a getRemoteAddr().

I'm not sure you can get a valid HttpServletRequest at the moment
WebServiceContext is being injected.
If you have a single service bean instance serving both plain HTTP and
SOAP requests and would to check the context info then you probably
need to inject

JAX-WS WebServiceContext
and
CXF JAX-RS MessageContext

and then check at runtime if it's jaxws or jaxrs chain which is being invoked:
http://cxf.apache.org/docs/jax-rs-and-jax-ws.html#JAX-RSandJAX-WS-Dealingwithcontexts

I was thinking of introducing a CXF extension, something like
ServiceContext, which could be used seamlessly irrespectively of
whether it was JAXWS or JAXRS invocation in progress. Loss of
portability vs simpler access to contexts. May get to it later on.
The other option is to check this info from CXF interceptors - a
single interceptor can be shared for this purpose.

Cheers, Sergey

>
> The soap request it being submitted using Apache HttpClient.
>
> here is some CXF output about the request:
>
> INFO: Inbound Message
> ----------------------------
> ID: 1
> Address: http://localhost:8080/GoldenKey/svc/soap
> Encoding: UTF-8
> Http-Method: POST
> Content-Type: text/xml; charset=utf-8
> Headers: {connection=[Keep-Alive], Content-Length=[387],
> content-type=[text/xml; charset=utf-8], host=[localhost:8080],
> user-agent=[Apache-HttpClient/4.1 (java 1.5)], x-forwarded-for=[This is my
> ip address: 127.0.0.1]}
> Payload: <soap:Envelope
> xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAddressTypes
> xmlns:ns2="http://com.upmc.tdc.server"><ns2:Application><applicationId>2a24907c-59c2-4415-b944-a5d1148544d1</applicationId></ns2:Application><ns2:User><username>myerscb</username></ns2:User><ns2:DataSourceType>EPCD</ns2:DataSourceType></ns2:getAddressTypes></soap:Body></soap:Envelope>
> --------------------------------------
>
> it certainly looks like the headers are there, even one that I inserted
> (x-forwarded-for).  But, when I attempt to try and access the headers
> through the request object, i get a null pointer exception.
>
> I am wondering what i am missing?  is there a different way to get header
> information for a soap request?
>
> Thanks for your help,
>
> Chris
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Getting-the-IP-Address-of-SOAP-Clients-works-for-REST-clients-but-not-for-SOAP-clients-tp4476334p4476334.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>



-- 
Sergey Beryozkin

Application Integration Division of Talend
http://sberyozkin.blogspot.com