You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Oliver Wulff <ow...@talend.com> on 2011/11/18 09:00:46 UTC

AW: Proxy object used in multi threaded case

Can anybody give me a hint where to extend this functionality in CXF itself?

Thanks
Oli

________________________________________
Von: Oliver Wulff [owulff@talend.com]
Gesendet: Mittwoch, 26. Oktober 2011 09:10
Bis: users@cxf.apache.org
Betreff: AW: Proxy object used in multi threaded case

Hi there

>>>
>> The SecureConv and IssuedToken interceptors current "sync" on the client
>> object to make sure this case works.   It definitely can be a performance
>> issue though.
>>>

I guess you mean this:

     STSClient client = STSUtils.getClient(message, "sts", itok);
                        AddressingProperties maps =
                            (AddressingProperties)message
                                .get("javax.xml.ws.addressing.context.outbound");
                        if (maps == null) {
                            maps = (AddressingProperties)message
                                .get("javax.xml.ws.addressing.context");
                        }
                        synchronized (client) {
                            try {


I was thinking of using Apache Commons Pool for the proxy objects. But before starting, I wanted to double check whether there are better ways thus I could contribute the enhancements back to the community. Maybe we could introduce a jaxws property for jaxws:client whether pooling should be used or not.

What is the best place to hook this functionality in (ClientFactoryBean, ClientProxyFactoryBean or in the ClientProxy thus it works to inject the proxy object in your impl class)?

Thanks
Oli
________________________________________
Von: Aki Yoshida [elakito@googlemail.com]
Gesendet: Mittwoch, 19. Oktober 2011 23:57
Bis: users@cxf.apache.org
Betreff: Re: Proxy object used in multi threaded case

2011/10/19 Aki Yoshida <el...@googlemail.com>:
> 2011/10/19 Daniel Kulp <dk...@apache.org>:
>> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
>>> Hi guys
>>>
>>> I've got a question with respect to a deployment of CXF in an intermediary
>>> scenario. The service implementation of the intermediary injects the proxy
>>> instance for the target service it will call. Of course, this is a multi
>>> threaded environment where the service implementation gets the current user
>>> as part of the incoming message (not ws-security).
>>>
>>> The target service expects to get a security token issued by the STS. The
>>> username is expected to be set for the proxy and the
>>> WSSUsernameCallbackHandler is configured to get the user from there.
>>>
>>> Here a snippet of the configuration:
>>>
>>>    <jaxws:client
>>> name="{http://www.example.org/contract/DoubleIt}DoubleItTransportIONABSTPor
>>> t" createdFromAPI="true"> <jaxws:properties>
>>>            <entry key="ws-security.sts.client">
>>>                <bean class="org.apache.cxf.ws.security.trust.STSClient">
>>>                    <constructor-arg ref="cxf"/>
>>>                    <property name="onBehalfOf"
>>> ref="delegationCallbackHandler" />
>>>
>>>
>>> The implementation of the intermediary service gets the BindingProvider and
>>> adds the username like this:
>>>
>>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME_PROPERTY,
>>> "myuser)
>>>
>>> Has the request context the scope of the current thread or is it tight to
>>> the proxy instance.
>>
>>
>> This is answered in the FAQ:
>>
>> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
>>
>>
>>> If latter, an intermediary must create a new proxy per
>>> request. If the former, what is the scope of the STSClient instance?
>>
>> Per proxy.
>
> If your service implementation is using your proxy and the number of
> actively used configurations is small, you can pool (or cache) your
> proxy instances in your service so that you don't need to create a new
> proxy per call.
>
> For other cases where there is no choice and there is only one proxy
> instance, it would probably be nice if CXF can introduce an option to
> make the request/response context objects thread-local. But this may
> be more complicated and may have some adverse effect.
>

I didn't see Dan's faq reference explaining that this thread-local
option is already provided.
so, please ignore my comment.

regards, aki

> regards, aki
>
>>
>>> If
>>> there are several requests coming in, the proxy instance is global, the
>>> request context is correlated with the thread (assumption) it might not
>>> work because there is only one STSClient instance.
>>
>> The SecureConv and IssuedToken interceptors current "sync" on the client
>> object to make sure this case works.   It definitely can be a performance
>> issue though.
>>
>>
>> --
>> Daniel Kulp
>> dkulp@apache.org
>> http://dankulp.com/blog
>> Talend - http://www.talend.com
>>
>

Re: AW: AW: Proxy object used in multi threaded case

Posted by Daniel Kulp <dk...@apache.org>.
On Monday, November 21, 2011 9:02:31 AM Oliver Wulff wrote:
> I was thinking in providing a pool of CXF client objects (not STS client
> objects).
> 
> IMHO, in general, I'd prefer to have no dependency whether a programmer uses
> one proxy instance for all requests or a new one for each request. The
> creation if a proxy instance is "expensive" (download wsdl from remote
> location, parsing (incl. policies), ...).

Well, if you holdon to at least one proxy, its not "as expensive" as the 
WSDLManager should hold on to the parsed/processed WSDL.    There is still 
quite a bit of annotation handling and such happening though.

Dan



> Therefore, I was thinking of a pool of CXF client objects (the parsed wsdl
> data could just be cloned (in case not thread safe)). Then, it would be
> fine to have a non thread safe STSClient also.
> 
> It should also address the other exceptions described here:
> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe
> 
> Thanks
> Oli
> ________________________________________
> Von: Daniel Kulp [dkulp@apache.org]
> Gesendet: Freitag, 18. November 2011 23:15
> Bis: users@cxf.apache.org
> Cc: Oliver Wulff
> Betreff: Re: AW: Proxy object used in multi threaded case
> 
> On Friday, November 18, 2011 8:00:46 AM Oliver Wulff wrote:
> > Can anybody give me a hint where to extend this functionality in CXF
> > itself?
> Well, I can give you workaround that should work with CXF right now:
> 
> Since the STSClient  is retrieved as a contextual property:
> STSClient client = (STSClient)message
>             .getContextualProperty(SecurityConstants.STS_CLIENT);
> 
> You can actually create a pool of STSClients and set that on the
> RequestContext of the proxy or the message on a per-request basis.   For
> example, an interceptor that runs before the IssuedTokenInterceptor could
> checkout a STSClient from a pool, stick it on the message, and then add an
> interceptor that runs later that sticks it back on the pool.  (and also in
> the handleFault).    Thus, you can still have a single proxy, but multiple
> STSClients.
> 
> 
> Longer term, one thing we could do is make the call to getClient first do
> something like:
> 
> STSClientFactory factory = message
>             .getContextualProperty(SecurityConstants.STS_CLIENT_FACTORY);
> if (factory != null) {
>     client = factory.createClient(...);
> } else {
>     client = (STSClient)message
>             .getContextualProperty(SecurityConstants.STS_CLIENT);
> }
> 
> or similar to introduce some sort of factory in there.   We'd have to add a
> "releaseClient" and add finally blocks in various places so the factory
> could get re-called.  (or, on the STSClient itself, have a release() method
> that a subclass could override to put it back in a pool)
> 
> Patch would be welcome.  :-)
> 
> 
> Dan
> 
> > Thanks
> > Oli
> > 
> > ________________________________________
> > Von: Oliver Wulff [owulff@talend.com]
> > Gesendet: Mittwoch, 26. Oktober 2011 09:10
> > Bis: users@cxf.apache.org
> > Betreff: AW: Proxy object used in multi threaded case
> > 
> > Hi there
> > 
> > >> The SecureConv and IssuedToken interceptors current "sync" on the
> > >> client
> > >> object to make sure this case works.   It definitely can be a
> > >> performance issue though.
> > 
> > I guess you mean this:
> >      STSClient client = STSUtils.getClient(message, "sts", itok);
> >      
> >                         AddressingProperties
> >                         maps =
> >                         
> >                             (AddressingPrope
> >                             rties)message
> > 
> > .get("javax.xml.ws.addressing.context.outbound"); if (maps == null) {
> > 
> >                             maps =
> >                             (AddressingProp
> >                             erties)message
> >                             
> >                                 .get("ja
> >                                 vax.xml.
> >                                 ws.addre
> >                                 ssing.co
> >                                 ntext");
> >                         
> >                         }
> >                         synchronized (client) {
> >                         
> >                             try {
> > 
> > I was thinking of using Apache Commons Pool for the proxy objects. But
> > before starting, I wanted to double check whether there are better ways
> > thus I could contribute the enhancements back to the community. Maybe we
> > could introduce a jaxws property for jaxws:client whether pooling should
> > be used or not.
> > 
> > What is the best place to hook this functionality in (ClientFactoryBean,
> > ClientProxyFactoryBean or in the ClientProxy thus it works to inject the
> > proxy object in your impl class)?
> > 
> > Thanks
> > Oli
> > ________________________________________
> > Von: Aki Yoshida [elakito@googlemail.com]
> > Gesendet: Mittwoch, 19. Oktober 2011 23:57
> > Bis: users@cxf.apache.org
> > Betreff: Re: Proxy object used in multi threaded case
> > 
> > 2011/10/19 Aki Yoshida <el...@googlemail.com>:
> > > 2011/10/19 Daniel Kulp <dk...@apache.org>:
> > >> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
> > >>> Hi guys
> > >>> 
> > >>> I've got a question with respect to a deployment of CXF in an
> > >>> intermediary scenario. The service implementation of the
> > >>> intermediary injects the proxy instance for the target service
> > >>> it
> > >>> will call. Of course, this is a multi threaded environment where
> > >>> the service implementation gets the current user as part of the
> > >>> incoming message (not ws-security).
> > >>> 
> > >>> The target service expects to get a security token issued by the
> > >>> STS. The username is expected to be set for the proxy and the
> > >>> WSSUsernameCallbackHandler is configured to get the user from
> > >>> there.
> > >>> 
> > >>> Here a snippet of the configuration:
> > >>>    <jaxws:client
> > >>> 
> > >>> name="{http://www.example.org/contract/DoubleIt}DoubleItTranspor
> > >>> tION
> > >>> ABSTPor t" createdFromAPI="true"> <jaxws:properties>
> > >>> 
> > >>>            <entry key="ws-security.sts.client">
> > >>>            
> > >>>                <bean
> > >>>                class="org.apache.cxf.ws.security.
> > >>>                tru
> > >>>                st.STSClient">>>>
> > >>>                
> > >>>                    <constructor-arg
> > >>>                    ref="cxf"/>
> > >>>                    <property
> > >>>                    name="onBehalfOf"
> > >>> 
> > >>> ref="delegationCallbackHandler" />
> > >>> 
> > >>> 
> > >>> The implementation of the intermediary service gets the
> > >>> BindingProvider and adds the username like this:
> > >>> 
> > >>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME
> > >>> _PRO
> > >>> PERTY, "myuser)
> > >>> 
> > >>> Has the request context the scope of the current thread or is it
> > >>> tight to the proxy instance.
> > >> 
> > >> This is answered in the FAQ:
> > >> 
> > >> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
> > >> 
> > >>> If latter, an intermediary must create a new proxy per
> > >>> request. If the former, what is the scope of the STSClient
> > >>> instance?
> > >> 
> > >> Per proxy.
> > > 
> > > If your service implementation is using your proxy and the number of
> > > actively used configurations is small, you can pool (or cache) your
> > > proxy instances in your service so that you don't need to create a
> > > new
> > > proxy per call.
> > > 
> > > For other cases where there is no choice and there is only one proxy
> > > instance, it would probably be nice if CXF can introduce an option
> > > to
> > > make the request/response context objects thread-local. But this may
> > > be more complicated and may have some adverse effect.
> > 
> > I didn't see Dan's faq reference explaining that this thread-local
> > option is already provided.
> > so, please ignore my comment.
> > 
> > regards, aki
> > 
> > > regards, aki
> > > 
> > >>> If
> > >>> there are several requests coming in, the proxy instance is
> > >>> global,
> > >>> the
> > >>> request context is correlated with the thread (assumption) it
> > >>> might
> > >>> not
> > >>> work because there is only one STSClient instance.
> > >> 
> > >> The SecureConv and IssuedToken interceptors current "sync" on the
> > >> client
> > >> object to make sure this case works.   It definitely can be a
> > >> performance issue though.
> > >> 
> > >> 
> > >> --
> > >> Daniel Kulp
> > >> dkulp@apache.org
> > >> http://dankulp.com/blog
> > >> Talend - http://www.talend.com
> 
> --
> Daniel Kulp
> dkulp@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

Re: AW: AW: Proxy object used in multi threaded case

Posted by skousouris <st...@hotmail.com>.
Oliver Wulff-2 wrote
> I was thinking in providing a pool of CXF client objects (not STS client
> objects).
> 
> IMHO, in general, I'd prefer to have no dependency whether a programmer
> uses one proxy instance for all requests or a new one for each request.
> The creation if a proxy instance is "expensive" (download wsdl from remote
> location, parsing (incl. policies), ...).
> 
> Therefore, I was thinking of a pool of CXF client objects (the parsed wsdl
> data could just be cloned (in case not thread safe)). Then, it would be
> fine to have a non thread safe STSClient also.
> 
> It should also address the other exceptions described here:
> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe
> 
> Thanks
> Oli

Hi Oli,

A little bit late but did you get to create such a pool in the end? I am
creating programmatically the proxy from within a Spring bean and it takes
around 500ms to do that when the whole call end-to-end takes no more than
600ms.

I have seen a few examples of creating pool of objects but am not sure 
a) if I should store the object of 
MyServiceObj = new MyService(WSDL_LOCATION, SERVICE)
 (I believe not as this is the thread safe and inexpensive Service class
instantiation which can also be created with the factory method MyServiceObj
= MyService.create(WSDL_LOCATION, SERVICE)

OR the 
MyServiceObj.getPort() (I belive this is the one needed to be pooled)

b) Once pooled I can have a mechanism to instantiate at context load (I
would assume) the pool and get/return the objects from my clients BUT at
return do we need to "clean" them (ie. if any changes to the context occur?)
else how does this make the port Thread Safe if it is littered of another
thread's context. Some pointers on the cleaning (I believe you may have a
clone of the context in your case but not sure how that would work) would
also be appreciated.

Thanks in advance



--
View this message in context: http://cxf.547215.n5.nabble.com/Proxy-object-used-in-multi-threaded-case-tp4917256p5718957.html
Sent from the cxf-user mailing list archive at Nabble.com.

AW: AW: Proxy object used in multi threaded case

Posted by Oliver Wulff <ow...@talend.com>.
I was thinking in providing a pool of CXF client objects (not STS client objects).

IMHO, in general, I'd prefer to have no dependency whether a programmer uses one proxy instance for all requests or a new one for each request. The creation if a proxy instance is "expensive" (download wsdl from remote location, parsing (incl. policies), ...).

Therefore, I was thinking of a pool of CXF client objects (the parsed wsdl data could just be cloned (in case not thread safe)). Then, it would be fine to have a non thread safe STSClient also.

It should also address the other exceptions described here:
http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe

Thanks
Oli
________________________________________
Von: Daniel Kulp [dkulp@apache.org]
Gesendet: Freitag, 18. November 2011 23:15
Bis: users@cxf.apache.org
Cc: Oliver Wulff
Betreff: Re: AW: Proxy object used in multi threaded case

On Friday, November 18, 2011 8:00:46 AM Oliver Wulff wrote:
> Can anybody give me a hint where to extend this functionality in CXF itself?

Well, I can give you workaround that should work with CXF right now:

Since the STSClient  is retrieved as a contextual property:
STSClient client = (STSClient)message
            .getContextualProperty(SecurityConstants.STS_CLIENT);

You can actually create a pool of STSClients and set that on the
RequestContext of the proxy or the message on a per-request basis.   For
example, an interceptor that runs before the IssuedTokenInterceptor could
checkout a STSClient from a pool, stick it on the message, and then add an
interceptor that runs later that sticks it back on the pool.  (and also in the
handleFault).    Thus, you can still have a single proxy, but multiple
STSClients.


Longer term, one thing we could do is make the call to getClient first do
something like:

STSClientFactory factory = message
            .getContextualProperty(SecurityConstants.STS_CLIENT_FACTORY);
if (factory != null) {
    client = factory.createClient(...);
} else {
    client = (STSClient)message
            .getContextualProperty(SecurityConstants.STS_CLIENT);
}

or similar to introduce some sort of factory in there.   We'd have to add a
"releaseClient" and add finally blocks in various places so the factory could
get re-called.  (or, on the STSClient itself, have a release() method that a
subclass could override to put it back in a pool)

Patch would be welcome.  :-)


Dan



>
> Thanks
> Oli
>
> ________________________________________
> Von: Oliver Wulff [owulff@talend.com]
> Gesendet: Mittwoch, 26. Oktober 2011 09:10
> Bis: users@cxf.apache.org
> Betreff: AW: Proxy object used in multi threaded case
>
> Hi there
>
> >> The SecureConv and IssuedToken interceptors current "sync" on the
> >> client
> >> object to make sure this case works.   It definitely can be a
> >> performance issue though.
>
> I guess you mean this:
>
>      STSClient client = STSUtils.getClient(message, "sts", itok);
>                         AddressingProperties maps =
>                             (AddressingProperties)message
>
> .get("javax.xml.ws.addressing.context.outbound"); if (maps == null) {
>                             maps = (AddressingProperties)message
>                                 .get("javax.xml.ws.addressing.context");
>                         }
>                         synchronized (client) {
>                             try {
>
>
> I was thinking of using Apache Commons Pool for the proxy objects. But
> before starting, I wanted to double check whether there are better ways
> thus I could contribute the enhancements back to the community. Maybe we
> could introduce a jaxws property for jaxws:client whether pooling should be
> used or not.
>
> What is the best place to hook this functionality in (ClientFactoryBean,
> ClientProxyFactoryBean or in the ClientProxy thus it works to inject the
> proxy object in your impl class)?
>
> Thanks
> Oli
> ________________________________________
> Von: Aki Yoshida [elakito@googlemail.com]
> Gesendet: Mittwoch, 19. Oktober 2011 23:57
> Bis: users@cxf.apache.org
> Betreff: Re: Proxy object used in multi threaded case
>
> 2011/10/19 Aki Yoshida <el...@googlemail.com>:
> > 2011/10/19 Daniel Kulp <dk...@apache.org>:
> >> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
> >>> Hi guys
> >>>
> >>> I've got a question with respect to a deployment of CXF in an
> >>> intermediary scenario. The service implementation of the
> >>> intermediary injects the proxy instance for the target service it
> >>> will call. Of course, this is a multi threaded environment where
> >>> the service implementation gets the current user as part of the
> >>> incoming message (not ws-security).
> >>>
> >>> The target service expects to get a security token issued by the
> >>> STS. The username is expected to be set for the proxy and the
> >>> WSSUsernameCallbackHandler is configured to get the user from there.
> >>>
> >>> Here a snippet of the configuration:
> >>>    <jaxws:client
> >>>
> >>> name="{http://www.example.org/contract/DoubleIt}DoubleItTransportION
> >>> ABSTPor t" createdFromAPI="true"> <jaxws:properties>
> >>>
> >>>            <entry key="ws-security.sts.client">
> >>>
> >>>                <bean
> >>>                class="org.apache.cxf.ws.security.tru
> >>>                st.STSClient">>>>
> >>>                    <constructor-arg ref="cxf"/>
> >>>                    <property name="onBehalfOf"
> >>>
> >>> ref="delegationCallbackHandler" />
> >>>
> >>>
> >>> The implementation of the intermediary service gets the
> >>> BindingProvider and adds the username like this:
> >>>
> >>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME_PRO
> >>> PERTY, "myuser)
> >>>
> >>> Has the request context the scope of the current thread or is it
> >>> tight to the proxy instance.
> >>
> >> This is answered in the FAQ:
> >>
> >> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
> >>
> >>> If latter, an intermediary must create a new proxy per
> >>> request. If the former, what is the scope of the STSClient instance?
> >>
> >> Per proxy.
> >
> > If your service implementation is using your proxy and the number of
> > actively used configurations is small, you can pool (or cache) your
> > proxy instances in your service so that you don't need to create a new
> > proxy per call.
> >
> > For other cases where there is no choice and there is only one proxy
> > instance, it would probably be nice if CXF can introduce an option to
> > make the request/response context objects thread-local. But this may
> > be more complicated and may have some adverse effect.
>
> I didn't see Dan's faq reference explaining that this thread-local
> option is already provided.
> so, please ignore my comment.
>
> regards, aki
>
> > regards, aki
> >
> >>> If
> >>> there are several requests coming in, the proxy instance is global,
> >>> the
> >>> request context is correlated with the thread (assumption) it might
> >>> not
> >>> work because there is only one STSClient instance.
> >>
> >> The SecureConv and IssuedToken interceptors current "sync" on the
> >> client
> >> object to make sure this case works.   It definitely can be a
> >> performance issue though.
> >>
> >>
> >> --
> >> Daniel Kulp
> >> dkulp@apache.org
> >> http://dankulp.com/blog
> >> Talend - http://www.talend.com
--
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

Re: AW: Proxy object used in multi threaded case

Posted by Daniel Kulp <dk...@apache.org>.
On Friday, November 18, 2011 8:00:46 AM Oliver Wulff wrote:
> Can anybody give me a hint where to extend this functionality in CXF itself?

Well, I can give you workaround that should work with CXF right now:

Since the STSClient  is retrieved as a contextual property:
STSClient client = (STSClient)message
            .getContextualProperty(SecurityConstants.STS_CLIENT);

You can actually create a pool of STSClients and set that on the 
RequestContext of the proxy or the message on a per-request basis.   For 
example, an interceptor that runs before the IssuedTokenInterceptor could 
checkout a STSClient from a pool, stick it on the message, and then add an 
interceptor that runs later that sticks it back on the pool.  (and also in the 
handleFault).    Thus, you can still have a single proxy, but multiple 
STSClients.


Longer term, one thing we could do is make the call to getClient first do 
something like:

STSClientFactory factory = message
            .getContextualProperty(SecurityConstants.STS_CLIENT_FACTORY);
if (factory != null) {
    client = factory.createClient(...);
} else {
    client = (STSClient)message
            .getContextualProperty(SecurityConstants.STS_CLIENT);
}

or similar to introduce some sort of factory in there.   We'd have to add a 
"releaseClient" and add finally blocks in various places so the factory could 
get re-called.  (or, on the STSClient itself, have a release() method that a 
subclass could override to put it back in a pool)

Patch would be welcome.  :-)


Dan



> 
> Thanks
> Oli
> 
> ________________________________________
> Von: Oliver Wulff [owulff@talend.com]
> Gesendet: Mittwoch, 26. Oktober 2011 09:10
> Bis: users@cxf.apache.org
> Betreff: AW: Proxy object used in multi threaded case
> 
> Hi there
> 
> >> The SecureConv and IssuedToken interceptors current "sync" on the
> >> client
> >> object to make sure this case works.   It definitely can be a
> >> performance issue though.
> 
> I guess you mean this:
> 
>      STSClient client = STSUtils.getClient(message, "sts", itok);
>                         AddressingProperties maps =
>                             (AddressingProperties)message
>                                
> .get("javax.xml.ws.addressing.context.outbound"); if (maps == null) {
>                             maps = (AddressingProperties)message
>                                 .get("javax.xml.ws.addressing.context");
>                         }
>                         synchronized (client) {
>                             try {
> 
> 
> I was thinking of using Apache Commons Pool for the proxy objects. But
> before starting, I wanted to double check whether there are better ways
> thus I could contribute the enhancements back to the community. Maybe we
> could introduce a jaxws property for jaxws:client whether pooling should be
> used or not.
> 
> What is the best place to hook this functionality in (ClientFactoryBean,
> ClientProxyFactoryBean or in the ClientProxy thus it works to inject the
> proxy object in your impl class)?
> 
> Thanks
> Oli
> ________________________________________
> Von: Aki Yoshida [elakito@googlemail.com]
> Gesendet: Mittwoch, 19. Oktober 2011 23:57
> Bis: users@cxf.apache.org
> Betreff: Re: Proxy object used in multi threaded case
> 
> 2011/10/19 Aki Yoshida <el...@googlemail.com>:
> > 2011/10/19 Daniel Kulp <dk...@apache.org>:
> >> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
> >>> Hi guys
> >>> 
> >>> I've got a question with respect to a deployment of CXF in an
> >>> intermediary scenario. The service implementation of the
> >>> intermediary injects the proxy instance for the target service it
> >>> will call. Of course, this is a multi threaded environment where
> >>> the service implementation gets the current user as part of the
> >>> incoming message (not ws-security).
> >>> 
> >>> The target service expects to get a security token issued by the
> >>> STS. The username is expected to be set for the proxy and the
> >>> WSSUsernameCallbackHandler is configured to get the user from there.
> >>> 
> >>> Here a snippet of the configuration:
> >>>    <jaxws:client
> >>> 
> >>> name="{http://www.example.org/contract/DoubleIt}DoubleItTransportION
> >>> ABSTPor t" createdFromAPI="true"> <jaxws:properties>
> >>> 
> >>>            <entry key="ws-security.sts.client">
> >>>            
> >>>                <bean
> >>>                class="org.apache.cxf.ws.security.tru
> >>>                st.STSClient">>>>                
> >>>                    <constructor-arg ref="cxf"/>
> >>>                    <property name="onBehalfOf"
> >>> 
> >>> ref="delegationCallbackHandler" />
> >>> 
> >>> 
> >>> The implementation of the intermediary service gets the
> >>> BindingProvider and adds the username like this:
> >>> 
> >>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME_PRO
> >>> PERTY, "myuser)
> >>> 
> >>> Has the request context the scope of the current thread or is it
> >>> tight to the proxy instance.
> >> 
> >> This is answered in the FAQ:
> >> 
> >> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
> >> 
> >>> If latter, an intermediary must create a new proxy per
> >>> request. If the former, what is the scope of the STSClient instance?
> >> 
> >> Per proxy.
> > 
> > If your service implementation is using your proxy and the number of
> > actively used configurations is small, you can pool (or cache) your
> > proxy instances in your service so that you don't need to create a new
> > proxy per call.
> > 
> > For other cases where there is no choice and there is only one proxy
> > instance, it would probably be nice if CXF can introduce an option to
> > make the request/response context objects thread-local. But this may
> > be more complicated and may have some adverse effect.
> 
> I didn't see Dan's faq reference explaining that this thread-local
> option is already provided.
> so, please ignore my comment.
> 
> regards, aki
> 
> > regards, aki
> > 
> >>> If
> >>> there are several requests coming in, the proxy instance is global,
> >>> the
> >>> request context is correlated with the thread (assumption) it might
> >>> not
> >>> work because there is only one STSClient instance.
> >> 
> >> The SecureConv and IssuedToken interceptors current "sync" on the
> >> client
> >> object to make sure this case works.   It definitely can be a
> >> performance issue though.
> >> 
> >> 
> >> --
> >> Daniel Kulp
> >> dkulp@apache.org
> >> http://dankulp.com/blog
> >> Talend - http://www.talend.com
-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

AW: AW: AW: Proxy object used in multi threaded case

Posted by Oliver Wulff <ow...@talend.com>.
>>>
Well, in this TYPE of case, the goal was that you would set
CACHE_ISSUED_TOKEN_IN_ENDPOINT to false to keep it from using the token stored
on the endpoint.
>>>
You mean, if it is an intermediary case, then CACHE_ISSUED_TOKEN_IN_ENDPOINT should be set to false?

>>>
However, it should then still call message.getProperty  to
get the token (note: *not* getContextualProperty).   In that case, you would
have an interceptor or something set the token on the message (or request
context) and it would get picked up.
>>>
Which getProperty method do you mean? Do you mean message.get(....)?

Just for sanity check... the difference between get(...) and getContextualProperty() is that the latter one inherits all the properties from the bus, service and endpoint, right?

>>>
Actually if you DO have an interceptor that runs prior to the
IssuedTokenInterceptorProvider and sets the TOKEN on the message, it should
work for you as the call to getContextualProperty will grab that prior to the
one stored on the endpoint.  
>>>
Yes, but maybe easier to fix in IssuedTokenInterceptorProvider directly. The difficulty is to figure out the token to be set on the message depending on the current context (incoming security token). The latter is ignored right now.
The IssuedTokenInterceptorProvider must figure out the current security context in each outgoing call as it will change for sure. There are two options:

1) Allways create an STSClient instance to trigger the callback handler because we need the token id of the onbehalfof token to figure out the associated token id:
                Element onBehalfOfToken = client.getOnBehalfOfToken();
                String id = getIdFromToken(onBehalfOfToken);
                if (cachedToken != null) {
                    Properties properties = cachedToken.getProperties();
                    if (properties != null && properties.containsKey(key)) {
                        String associatedToken = properties.getProperty(key);
                        SecurityToken issuedToken = tokenStore.getToken(associatedToken);
                    }
                }

2) As the intermediary is a service provider also, there is a WebServiceContext available (correlated with TLS), we might use the principal name as the key into the tokenstore to retrieve the associated token id or as a key to retrieve the cached "onbehalfof" token (one additional indirection).

How can I access the WebServiceContext (incoming message) in a out interceptor? In this case, the current message is for the outgoing call but the WebServiceContext should be accessible as it is correlated with the current thread.

IMHO, I'd go with 2) as I don't need an STS instance.

Thoughts?

Thanks
Oli

________________________________________
Von: Daniel Kulp [dkulp@apache.org]
Gesendet: Freitag, 18. November 2011 23:06
Bis: users@cxf.apache.org
Cc: Oliver Wulff
Betreff: Re: AW: AW: Proxy object used in multi threaded case

On Friday, November 18, 2011 3:41:04 PM Oliver Wulff wrote:
> Now, the IssuedTokenInterceptorProvider is called:
>         private SecurityToken retrieveCachedToken(Message message) {
>             boolean cacheIssuedToken =
>                 MessageUtils.getContextualBoolean(
>                     message,
> SecurityConstants.CACHE_ISSUED_TOKEN_IN_ENDPOINT, true );
>             SecurityToken tok = null;
>             if (cacheIssuedToken) {
>                 tok =
> (SecurityToken)message.getContextualProperty(SecurityConstants.TOKEN); if
> (tok == null) {
>                     String tokId =
> (String)message.getContextualProperty(SecurityConstants.TOKEN_ID); if
> (tokId != null) {
>                         tok = getTokenStore(message).getToken(tokId);
>                     }
>                 }
>             }
>             return tok;
>         }
>
> The problem is that the check whether there is already a token cached
> (retrieveCachedToken) doesn't consider the current user context. It doesn't
> check is there a token cached for the user xyz. This information can be
> retrieved only if the delegation callback handler is called first or we
> check the WebServiceContext.

Well, in this TYPE of case, the goal was that you would set
CACHE_ISSUED_TOKEN_IN_ENDPOINT to false to keep it from using the token stored
on the endpoint.   However, it should then still call message.getProperty  to
get the token (note: *not* getContextualProperty).   In that case, you would
have an interceptor or something set the token on the message (or request
context) and it would get picked up.   The problem is that this is obviously
not working in this case as the call the getProperty isn't there.  :-(    If
you set the  CACHE_ISSUED_TOKEN_IN_ENDPOINT to false, it will always call off
to the STS.

Actually if you DO have an interceptor that runs prior to the
IssuedTokenInterceptorProvider and sets the TOKEN on the message, it should
work for you as the call to getContextualProperty will grab that prior to the
one stored on the endpoint.

Dan




> What do you think?
>
> Thanks
> Oli
>
>
> ________________________________________
> Von: Daniel Kulp [dkulp@apache.org]
> Gesendet: Freitag, 18. November 2011 15:40
> Bis: users@cxf.apache.org
> Cc: Oliver Wulff
> Betreff: Re: AW: Proxy object used in multi threaded case
>
> On Friday, November 18, 2011 10:39:19 AM Oliver Wulff wrote:
> > Maybe one other point to consider is the way how the
> > IssuedTokenInterceptorProvider handles the TokenStore...
> >
> >     static final TokenStore getTokenStore(Message message) {
> >
> >         EndpointInfo info =
> >
> > message.getExchange().get(Endpoint.class).getEndpointInfo();
> > synchronized
> > (info) {
> >
> >             TokenStore tokenStore =
> >
> > (TokenStore)message.getContextualProperty(TokenStore.class.getName());
> > if
> > (tokenStore == null) {
> >
> >                 tokenStore =
> >
> > (TokenStore)info.getProperty(TokenStore.class.getName()); }
> >
> >             if (tokenStore == null) {
> >
> >                 tokenStore = new MemoryTokenStore();
> >                 info.setProperty(TokenStore.class.getNam
> >                 e(), tokenStore);
> >
> >             }
> >             return tokenStore;
> >
> >         }
> >
> >     }
> >
> > The TokenStore is tight to the proxy object / exchange object (CXF
> > client) which means if there is a pool of client objects I'd like to
> > avoid that each uses its own TokenStore.
> >
> > IMHO, the TokenStore should be global (tight to the bus) and get at
> > invocation time a client object of a pool for performance reasons.
>
> You can do that already.   If you notice:
>
> message.getContextualProperty(TokenStore.class.getName())
>
> it's checking for a contextual property.   Thus, you can configure a
> TokenStore on the bus and it will be picked up and used.   We generally
> don't do this by default as we usually want all the tokens used by that
> proxy to get garbage collected when the client is discarded.   Anything
> stored on the endpoint would just "go away".
>
> Also, the TokenStore has a couple synchronized things it (to handle expires
> and such) and having a BUNCH of things using a single token store when they
> don't need to COULD introduce another choke point.
>
> The other thing to be careful of is if you can have Tokens then used by
> other services/clients that shouldn't be using them.    We'd have to dig
> into the code a little more to check that.
>
> Dan
>
> > Thanks
> > Oli
> > ________________________________________
> > Von: Oliver Wulff [owulff@talend.com]
> > Gesendet: Freitag, 18. November 2011 09:00
> > Bis: users@cxf.apache.org
> > Betreff: AW: Proxy object used in multi threaded case
> >
> > Can anybody give me a hint where to extend this functionality in CXF
> > itself?
> >
> > Thanks
> > Oli
> >
> > ________________________________________
> > Von: Oliver Wulff [owulff@talend.com]
> > Gesendet: Mittwoch, 26. Oktober 2011 09:10
> > Bis: users@cxf.apache.org
> > Betreff: AW: Proxy object used in multi threaded case
> >
> > Hi there
> >
> > >> The SecureConv and IssuedToken interceptors current "sync" on the
> > >> client
> > >> object to make sure this case works.   It definitely can be a
> > >> performance issue though.
> >
> > I guess you mean this:
> >      STSClient client = STSUtils.getClient(message, "sts", itok);
> >
> >                         AddressingProperties
> >                         maps =
> >
> >                             (AddressingPrope
> >                             rties)message
> >
> > .get("javax.xml.ws.addressing.context.outbound"); if (maps == null) {
> >
> >                             maps =
> >                             (AddressingProp
> >                             erties)message
> >
> >                                 .get("ja
> >                                 vax.xml.
> >                                 ws.addre
> >                                 ssing.co
> >                                 ntext");
> >
> >                         }
> >                         synchronized (client) {
> >
> >                             try {
> >
> > I was thinking of using Apache Commons Pool for the proxy objects. But
> > before starting, I wanted to double check whether there are better ways
> > thus I could contribute the enhancements back to the community. Maybe we
> > could introduce a jaxws property for jaxws:client whether pooling should
> > be used or not.
> >
> > What is the best place to hook this functionality in (ClientFactoryBean,
> > ClientProxyFactoryBean or in the ClientProxy thus it works to inject the
> > proxy object in your impl class)?
> >
> > Thanks
> > Oli
> > ________________________________________
> > Von: Aki Yoshida [elakito@googlemail.com]
> > Gesendet: Mittwoch, 19. Oktober 2011 23:57
> > Bis: users@cxf.apache.org
> > Betreff: Re: Proxy object used in multi threaded case
> >
> > 2011/10/19 Aki Yoshida <el...@googlemail.com>:
> > > 2011/10/19 Daniel Kulp <dk...@apache.org>:
> > >> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
> > >>> Hi guys
> > >>>
> > >>> I've got a question with respect to a deployment of CXF in an
> > >>> intermediary scenario. The service implementation of the
> > >>> intermediary injects the proxy instance for the target service
> > >>> it
> > >>> will call. Of course, this is a multi threaded environment where
> > >>> the service implementation gets the current user as part of the
> > >>> incoming message (not ws-security).
> > >>>
> > >>> The target service expects to get a security token issued by the
> > >>> STS. The username is expected to be set for the proxy and the
> > >>> WSSUsernameCallbackHandler is configured to get the user from
> > >>> there.
> > >>>
> > >>> Here a snippet of the configuration:
> > >>>    <jaxws:client
> > >>>
> > >>> name="{http://www.example.org/contract/DoubleIt}DoubleItTranspor
> > >>> tION
> > >>> ABSTPor t" createdFromAPI="true"> <jaxws:properties>
> > >>>
> > >>>            <entry key="ws-security.sts.client">
> > >>>
> > >>>                <bean
> > >>>                class="org.apache.cxf.ws.security.
> > >>>                tru
> > >>>                st.STSClient">>>>
> > >>>
> > >>>                    <constructor-arg
> > >>>                    ref="cxf"/>
> > >>>                    <property
> > >>>                    name="onBehalfOf"
> > >>>
> > >>> ref="delegationCallbackHandler" />
> > >>>
> > >>>
> > >>> The implementation of the intermediary service gets the
> > >>> BindingProvider and adds the username like this:
> > >>>
> > >>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME
> > >>> _PRO
> > >>> PERTY, "myuser)
> > >>>
> > >>> Has the request context the scope of the current thread or is it
> > >>> tight to the proxy instance.
> > >>
> > >> This is answered in the FAQ:
> > >>
> > >> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
> > >>
> > >>> If latter, an intermediary must create a new proxy per
> > >>> request. If the former, what is the scope of the STSClient
> > >>> instance?
> > >>
> > >> Per proxy.
> > >
> > > If your service implementation is using your proxy and the number of
> > > actively used configurations is small, you can pool (or cache) your
> > > proxy instances in your service so that you don't need to create a
> > > new
> > > proxy per call.
> > >
> > > For other cases where there is no choice and there is only one proxy
> > > instance, it would probably be nice if CXF can introduce an option
> > > to
> > > make the request/response context objects thread-local. But this may
> > > be more complicated and may have some adverse effect.
> >
> > I didn't see Dan's faq reference explaining that this thread-local
> > option is already provided.
> > so, please ignore my comment.
> >
> > regards, aki
> >
> > > regards, aki
> > >
> > >>> If
> > >>> there are several requests coming in, the proxy instance is
> > >>> global,
> > >>> the
> > >>> request context is correlated with the thread (assumption) it
> > >>> might
> > >>> not
> > >>> work because there is only one STSClient instance.
> > >>
> > >> The SecureConv and IssuedToken interceptors current "sync" on the
> > >> client
> > >> object to make sure this case works.   It definitely can be a
> > >> performance issue though.
> > >>
> > >>
> > >> --
> > >> Daniel Kulp
> > >> dkulp@apache.org
> > >> http://dankulp.com/blog
> > >> Talend - http://www.talend.com
>
> --
> Daniel Kulp
> dkulp@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
--
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

Re: AW: AW: Proxy object used in multi threaded case

Posted by Daniel Kulp <dk...@apache.org>.
On Friday, November 18, 2011 3:41:04 PM Oliver Wulff wrote:
> Now, the IssuedTokenInterceptorProvider is called:
>         private SecurityToken retrieveCachedToken(Message message) {
>             boolean cacheIssuedToken =
>                 MessageUtils.getContextualBoolean(
>                     message,
> SecurityConstants.CACHE_ISSUED_TOKEN_IN_ENDPOINT, true );
>             SecurityToken tok = null;
>             if (cacheIssuedToken) {
>                 tok =
> (SecurityToken)message.getContextualProperty(SecurityConstants.TOKEN); if
> (tok == null) {
>                     String tokId =
> (String)message.getContextualProperty(SecurityConstants.TOKEN_ID); if
> (tokId != null) {
>                         tok = getTokenStore(message).getToken(tokId);
>                     }
>                 }
>             }
>             return tok;
>         }
> 
> The problem is that the check whether there is already a token cached
> (retrieveCachedToken) doesn't consider the current user context. It doesn't
> check is there a token cached for the user xyz. This information can be
> retrieved only if the delegation callback handler is called first or we
> check the WebServiceContext.

Well, in this TYPE of case, the goal was that you would set 
CACHE_ISSUED_TOKEN_IN_ENDPOINT to false to keep it from using the token stored 
on the endpoint.   However, it should then still call message.getProperty  to 
get the token (note: *not* getContextualProperty).   In that case, you would 
have an interceptor or something set the token on the message (or request 
context) and it would get picked up.   The problem is that this is obviously 
not working in this case as the call the getProperty isn't there.  :-(    If 
you set the  CACHE_ISSUED_TOKEN_IN_ENDPOINT to false, it will always call off 
to the STS.   

Actually if you DO have an interceptor that runs prior to the 
IssuedTokenInterceptorProvider and sets the TOKEN on the message, it should 
work for you as the call to getContextualProperty will grab that prior to the 
one stored on the endpoint.  

Dan




> What do you think?
> 
> Thanks
> Oli
> 
> 
> ________________________________________
> Von: Daniel Kulp [dkulp@apache.org]
> Gesendet: Freitag, 18. November 2011 15:40
> Bis: users@cxf.apache.org
> Cc: Oliver Wulff
> Betreff: Re: AW: Proxy object used in multi threaded case
> 
> On Friday, November 18, 2011 10:39:19 AM Oliver Wulff wrote:
> > Maybe one other point to consider is the way how the
> > IssuedTokenInterceptorProvider handles the TokenStore...
> > 
> >     static final TokenStore getTokenStore(Message message) {
> >     
> >         EndpointInfo info =
> > 
> > message.getExchange().get(Endpoint.class).getEndpointInfo();
> > synchronized
> > (info) {
> > 
> >             TokenStore tokenStore =
> > 
> > (TokenStore)message.getContextualProperty(TokenStore.class.getName());
> > if
> > (tokenStore == null) {
> > 
> >                 tokenStore =
> > 
> > (TokenStore)info.getProperty(TokenStore.class.getName()); }
> > 
> >             if (tokenStore == null) {
> >             
> >                 tokenStore = new MemoryTokenStore();
> >                 info.setProperty(TokenStore.class.getNam
> >                 e(), tokenStore);
> >             
> >             }
> >             return tokenStore;
> >         
> >         }
> >     
> >     }
> > 
> > The TokenStore is tight to the proxy object / exchange object (CXF
> > client) which means if there is a pool of client objects I'd like to
> > avoid that each uses its own TokenStore.
> > 
> > IMHO, the TokenStore should be global (tight to the bus) and get at
> > invocation time a client object of a pool for performance reasons.
> 
> You can do that already.   If you notice:
> 
> message.getContextualProperty(TokenStore.class.getName())
> 
> it's checking for a contextual property.   Thus, you can configure a
> TokenStore on the bus and it will be picked up and used.   We generally
> don't do this by default as we usually want all the tokens used by that
> proxy to get garbage collected when the client is discarded.   Anything
> stored on the endpoint would just "go away".
> 
> Also, the TokenStore has a couple synchronized things it (to handle expires
> and such) and having a BUNCH of things using a single token store when they
> don't need to COULD introduce another choke point.
> 
> The other thing to be careful of is if you can have Tokens then used by
> other services/clients that shouldn't be using them.    We'd have to dig
> into the code a little more to check that.
> 
> Dan
> 
> > Thanks
> > Oli
> > ________________________________________
> > Von: Oliver Wulff [owulff@talend.com]
> > Gesendet: Freitag, 18. November 2011 09:00
> > Bis: users@cxf.apache.org
> > Betreff: AW: Proxy object used in multi threaded case
> > 
> > Can anybody give me a hint where to extend this functionality in CXF
> > itself?
> > 
> > Thanks
> > Oli
> > 
> > ________________________________________
> > Von: Oliver Wulff [owulff@talend.com]
> > Gesendet: Mittwoch, 26. Oktober 2011 09:10
> > Bis: users@cxf.apache.org
> > Betreff: AW: Proxy object used in multi threaded case
> > 
> > Hi there
> > 
> > >> The SecureConv and IssuedToken interceptors current "sync" on the
> > >> client
> > >> object to make sure this case works.   It definitely can be a
> > >> performance issue though.
> > 
> > I guess you mean this:
> >      STSClient client = STSUtils.getClient(message, "sts", itok);
> >      
> >                         AddressingProperties
> >                         maps =
> >                         
> >                             (AddressingPrope
> >                             rties)message
> > 
> > .get("javax.xml.ws.addressing.context.outbound"); if (maps == null) {
> > 
> >                             maps =
> >                             (AddressingProp
> >                             erties)message
> >                             
> >                                 .get("ja
> >                                 vax.xml.
> >                                 ws.addre
> >                                 ssing.co
> >                                 ntext");
> >                         
> >                         }
> >                         synchronized (client) {
> >                         
> >                             try {
> > 
> > I was thinking of using Apache Commons Pool for the proxy objects. But
> > before starting, I wanted to double check whether there are better ways
> > thus I could contribute the enhancements back to the community. Maybe we
> > could introduce a jaxws property for jaxws:client whether pooling should
> > be used or not.
> > 
> > What is the best place to hook this functionality in (ClientFactoryBean,
> > ClientProxyFactoryBean or in the ClientProxy thus it works to inject the
> > proxy object in your impl class)?
> > 
> > Thanks
> > Oli
> > ________________________________________
> > Von: Aki Yoshida [elakito@googlemail.com]
> > Gesendet: Mittwoch, 19. Oktober 2011 23:57
> > Bis: users@cxf.apache.org
> > Betreff: Re: Proxy object used in multi threaded case
> > 
> > 2011/10/19 Aki Yoshida <el...@googlemail.com>:
> > > 2011/10/19 Daniel Kulp <dk...@apache.org>:
> > >> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
> > >>> Hi guys
> > >>> 
> > >>> I've got a question with respect to a deployment of CXF in an
> > >>> intermediary scenario. The service implementation of the
> > >>> intermediary injects the proxy instance for the target service
> > >>> it
> > >>> will call. Of course, this is a multi threaded environment where
> > >>> the service implementation gets the current user as part of the
> > >>> incoming message (not ws-security).
> > >>> 
> > >>> The target service expects to get a security token issued by the
> > >>> STS. The username is expected to be set for the proxy and the
> > >>> WSSUsernameCallbackHandler is configured to get the user from
> > >>> there.
> > >>> 
> > >>> Here a snippet of the configuration:
> > >>>    <jaxws:client
> > >>> 
> > >>> name="{http://www.example.org/contract/DoubleIt}DoubleItTranspor
> > >>> tION
> > >>> ABSTPor t" createdFromAPI="true"> <jaxws:properties>
> > >>> 
> > >>>            <entry key="ws-security.sts.client">
> > >>>            
> > >>>                <bean
> > >>>                class="org.apache.cxf.ws.security.
> > >>>                tru
> > >>>                st.STSClient">>>>
> > >>>                
> > >>>                    <constructor-arg
> > >>>                    ref="cxf"/>
> > >>>                    <property
> > >>>                    name="onBehalfOf"
> > >>> 
> > >>> ref="delegationCallbackHandler" />
> > >>> 
> > >>> 
> > >>> The implementation of the intermediary service gets the
> > >>> BindingProvider and adds the username like this:
> > >>> 
> > >>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME
> > >>> _PRO
> > >>> PERTY, "myuser)
> > >>> 
> > >>> Has the request context the scope of the current thread or is it
> > >>> tight to the proxy instance.
> > >> 
> > >> This is answered in the FAQ:
> > >> 
> > >> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
> > >> 
> > >>> If latter, an intermediary must create a new proxy per
> > >>> request. If the former, what is the scope of the STSClient
> > >>> instance?
> > >> 
> > >> Per proxy.
> > > 
> > > If your service implementation is using your proxy and the number of
> > > actively used configurations is small, you can pool (or cache) your
> > > proxy instances in your service so that you don't need to create a
> > > new
> > > proxy per call.
> > > 
> > > For other cases where there is no choice and there is only one proxy
> > > instance, it would probably be nice if CXF can introduce an option
> > > to
> > > make the request/response context objects thread-local. But this may
> > > be more complicated and may have some adverse effect.
> > 
> > I didn't see Dan's faq reference explaining that this thread-local
> > option is already provided.
> > so, please ignore my comment.
> > 
> > regards, aki
> > 
> > > regards, aki
> > > 
> > >>> If
> > >>> there are several requests coming in, the proxy instance is
> > >>> global,
> > >>> the
> > >>> request context is correlated with the thread (assumption) it
> > >>> might
> > >>> not
> > >>> work because there is only one STSClient instance.
> > >> 
> > >> The SecureConv and IssuedToken interceptors current "sync" on the
> > >> client
> > >> object to make sure this case works.   It definitely can be a
> > >> performance issue though.
> > >> 
> > >> 
> > >> --
> > >> Daniel Kulp
> > >> dkulp@apache.org
> > >> http://dankulp.com/blog
> > >> Talend - http://www.talend.com
> 
> --
> Daniel Kulp
> dkulp@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

AW: AW: Proxy object used in multi threaded case

Posted by Oliver Wulff <ow...@talend.com>.
>>>
We generally don't
do this by default as we usually want all the tokens used by that proxy to get
garbage collected when the client is discarded.   Anything stored on the
endpoint would just "go away". 
>>>
Understand. If the proxy is instantiated by spring with default scope, it won't be removed as long as the bus is up and running. But we have to be careful that the TokenStore is not filled with a lot of expired tokens.

>>>
We'd have to dig into the code a little more to check that.
>>>
I think so too. I've now debugged my code because I noticed that my intermediary always sends the cached token which has been issued on behalf of the first user who triggered the outbound call.

My application looks like this. A user is logged in to a web application and a SAML token is stored in the thread local storage (till to this stage, it's CXF independent). A custom callback handler is configured for the STSClient to provide the STSClient the SAML token:
<property name="onBehalfOf" ref="delegationCallbackHandler" />

Now, the IssuedTokenInterceptorProvider is called:

...
        public void handleMessage(Message message) throws Fault {
            AssertionInfoMap aim = message.get(AssertionInfoMap.class);
            // extract Assertion information
            if (aim != null) {
                Collection<AssertionInfo> ais = aim.get(SP12Constants.ISSUED_TOKEN);
                if (ais == null || ais.isEmpty()) {
                    return;
                }
                if (isRequestor(message)) {
                    IssuedToken itok = (IssuedToken)ais.iterator().next().getAssertion();
                    
                    SecurityToken tok = retrieveCachedToken(message);
                    if (tok == null) {

...

        private SecurityToken retrieveCachedToken(Message message) {
            boolean cacheIssuedToken = 
                MessageUtils.getContextualBoolean(
                    message, SecurityConstants.CACHE_ISSUED_TOKEN_IN_ENDPOINT, true
                );
            SecurityToken tok = null;
            if (cacheIssuedToken) {
                tok = (SecurityToken)message.getContextualProperty(SecurityConstants.TOKEN);
                if (tok == null) {
                    String tokId = (String)message.getContextualProperty(SecurityConstants.TOKEN_ID);
                    if (tokId != null) {
                        tok = getTokenStore(message).getToken(tokId);
                    }
                }
            }
            return tok;
        }

The problem is that the check whether there is already a token cached (retrieveCachedToken) doesn't consider the current user context. It doesn't check is there a token cached for the user xyz. This information can be retrieved only if the delegation callback handler is called first or we check the WebServiceContext.

What do you think?

Thanks
Oli


________________________________________
Von: Daniel Kulp [dkulp@apache.org]
Gesendet: Freitag, 18. November 2011 15:40
Bis: users@cxf.apache.org
Cc: Oliver Wulff
Betreff: Re: AW: Proxy object used in multi threaded case

On Friday, November 18, 2011 10:39:19 AM Oliver Wulff wrote:
> Maybe one other point to consider is the way how the
> IssuedTokenInterceptorProvider handles the TokenStore...
>
>     static final TokenStore getTokenStore(Message message) {
>         EndpointInfo info =
> message.getExchange().get(Endpoint.class).getEndpointInfo(); synchronized
> (info) {
>             TokenStore tokenStore =
> (TokenStore)message.getContextualProperty(TokenStore.class.getName()); if
> (tokenStore == null) {
>                 tokenStore =
> (TokenStore)info.getProperty(TokenStore.class.getName()); }
>             if (tokenStore == null) {
>                 tokenStore = new MemoryTokenStore();
>                 info.setProperty(TokenStore.class.getName(), tokenStore);
>             }
>             return tokenStore;
>         }
>     }
>
> The TokenStore is tight to the proxy object / exchange object (CXF client)
> which means if there is a pool of client objects I'd like to avoid that
> each uses its own TokenStore.
>
> IMHO, the TokenStore should be global (tight to the bus) and get at
> invocation time a client object of a pool for performance reasons.

You can do that already.   If you notice:

message.getContextualProperty(TokenStore.class.getName())

it's checking for a contextual property.   Thus, you can configure a
TokenStore on the bus and it will be picked up and used.   We generally don't
do this by default as we usually want all the tokens used by that proxy to get
garbage collected when the client is discarded.   Anything stored on the
endpoint would just "go away".

Also, the TokenStore has a couple synchronized things it (to handle expires
and such) and having a BUNCH of things using a single token store when they
don't need to COULD introduce another choke point.

The other thing to be careful of is if you can have Tokens then used by other
services/clients that shouldn't be using them.    We'd have to dig into the
code a little more to check that.

Dan


>
> Thanks
> Oli
> ________________________________________
> Von: Oliver Wulff [owulff@talend.com]
> Gesendet: Freitag, 18. November 2011 09:00
> Bis: users@cxf.apache.org
> Betreff: AW: Proxy object used in multi threaded case
>
> Can anybody give me a hint where to extend this functionality in CXF itself?
>
> Thanks
> Oli
>
> ________________________________________
> Von: Oliver Wulff [owulff@talend.com]
> Gesendet: Mittwoch, 26. Oktober 2011 09:10
> Bis: users@cxf.apache.org
> Betreff: AW: Proxy object used in multi threaded case
>
> Hi there
>
> >> The SecureConv and IssuedToken interceptors current "sync" on the
> >> client
> >> object to make sure this case works.   It definitely can be a
> >> performance issue though.
>
> I guess you mean this:
>
>      STSClient client = STSUtils.getClient(message, "sts", itok);
>                         AddressingProperties maps =
>                             (AddressingProperties)message
>
> .get("javax.xml.ws.addressing.context.outbound"); if (maps == null) {
>                             maps = (AddressingProperties)message
>                                 .get("javax.xml.ws.addressing.context");
>                         }
>                         synchronized (client) {
>                             try {
>
>
> I was thinking of using Apache Commons Pool for the proxy objects. But
> before starting, I wanted to double check whether there are better ways
> thus I could contribute the enhancements back to the community. Maybe we
> could introduce a jaxws property for jaxws:client whether pooling should be
> used or not.
>
> What is the best place to hook this functionality in (ClientFactoryBean,
> ClientProxyFactoryBean or in the ClientProxy thus it works to inject the
> proxy object in your impl class)?
>
> Thanks
> Oli
> ________________________________________
> Von: Aki Yoshida [elakito@googlemail.com]
> Gesendet: Mittwoch, 19. Oktober 2011 23:57
> Bis: users@cxf.apache.org
> Betreff: Re: Proxy object used in multi threaded case
>
> 2011/10/19 Aki Yoshida <el...@googlemail.com>:
> > 2011/10/19 Daniel Kulp <dk...@apache.org>:
> >> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
> >>> Hi guys
> >>>
> >>> I've got a question with respect to a deployment of CXF in an
> >>> intermediary scenario. The service implementation of the
> >>> intermediary injects the proxy instance for the target service it
> >>> will call. Of course, this is a multi threaded environment where
> >>> the service implementation gets the current user as part of the
> >>> incoming message (not ws-security).
> >>>
> >>> The target service expects to get a security token issued by the
> >>> STS. The username is expected to be set for the proxy and the
> >>> WSSUsernameCallbackHandler is configured to get the user from there.
> >>>
> >>> Here a snippet of the configuration:
> >>>    <jaxws:client
> >>>
> >>> name="{http://www.example.org/contract/DoubleIt}DoubleItTransportION
> >>> ABSTPor t" createdFromAPI="true"> <jaxws:properties>
> >>>
> >>>            <entry key="ws-security.sts.client">
> >>>
> >>>                <bean
> >>>                class="org.apache.cxf.ws.security.tru
> >>>                st.STSClient">>>>
> >>>                    <constructor-arg ref="cxf"/>
> >>>                    <property name="onBehalfOf"
> >>>
> >>> ref="delegationCallbackHandler" />
> >>>
> >>>
> >>> The implementation of the intermediary service gets the
> >>> BindingProvider and adds the username like this:
> >>>
> >>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME_PRO
> >>> PERTY, "myuser)
> >>>
> >>> Has the request context the scope of the current thread or is it
> >>> tight to the proxy instance.
> >>
> >> This is answered in the FAQ:
> >>
> >> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
> >>
> >>> If latter, an intermediary must create a new proxy per
> >>> request. If the former, what is the scope of the STSClient instance?
> >>
> >> Per proxy.
> >
> > If your service implementation is using your proxy and the number of
> > actively used configurations is small, you can pool (or cache) your
> > proxy instances in your service so that you don't need to create a new
> > proxy per call.
> >
> > For other cases where there is no choice and there is only one proxy
> > instance, it would probably be nice if CXF can introduce an option to
> > make the request/response context objects thread-local. But this may
> > be more complicated and may have some adverse effect.
>
> I didn't see Dan's faq reference explaining that this thread-local
> option is already provided.
> so, please ignore my comment.
>
> regards, aki
>
> > regards, aki
> >
> >>> If
> >>> there are several requests coming in, the proxy instance is global,
> >>> the
> >>> request context is correlated with the thread (assumption) it might
> >>> not
> >>> work because there is only one STSClient instance.
> >>
> >> The SecureConv and IssuedToken interceptors current "sync" on the
> >> client
> >> object to make sure this case works.   It definitely can be a
> >> performance issue though.
> >>
> >>
> >> --
> >> Daniel Kulp
> >> dkulp@apache.org
> >> http://dankulp.com/blog
> >> Talend - http://www.talend.com
--
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

Re: AW: Proxy object used in multi threaded case

Posted by Daniel Kulp <dk...@apache.org>.
On Friday, November 18, 2011 10:39:19 AM Oliver Wulff wrote:
> Maybe one other point to consider is the way how the
> IssuedTokenInterceptorProvider handles the TokenStore...
> 
>     static final TokenStore getTokenStore(Message message) {
>         EndpointInfo info =
> message.getExchange().get(Endpoint.class).getEndpointInfo(); synchronized
> (info) {
>             TokenStore tokenStore =
> (TokenStore)message.getContextualProperty(TokenStore.class.getName()); if
> (tokenStore == null) {
>                 tokenStore =
> (TokenStore)info.getProperty(TokenStore.class.getName()); }
>             if (tokenStore == null) {
>                 tokenStore = new MemoryTokenStore();
>                 info.setProperty(TokenStore.class.getName(), tokenStore);
>             }
>             return tokenStore;
>         }
>     }
> 
> The TokenStore is tight to the proxy object / exchange object (CXF client)
> which means if there is a pool of client objects I'd like to avoid that
> each uses its own TokenStore.
> 
> IMHO, the TokenStore should be global (tight to the bus) and get at
> invocation time a client object of a pool for performance reasons.

You can do that already.   If you notice:

message.getContextualProperty(TokenStore.class.getName())

it's checking for a contextual property.   Thus, you can configure a 
TokenStore on the bus and it will be picked up and used.   We generally don't 
do this by default as we usually want all the tokens used by that proxy to get 
garbage collected when the client is discarded.   Anything stored on the 
endpoint would just "go away".   

Also, the TokenStore has a couple synchronized things it (to handle expires 
and such) and having a BUNCH of things using a single token store when they 
don't need to COULD introduce another choke point.   

The other thing to be careful of is if you can have Tokens then used by other 
services/clients that shouldn't be using them.    We'd have to dig into the 
code a little more to check that.

Dan


> 
> Thanks
> Oli
> ________________________________________
> Von: Oliver Wulff [owulff@talend.com]
> Gesendet: Freitag, 18. November 2011 09:00
> Bis: users@cxf.apache.org
> Betreff: AW: Proxy object used in multi threaded case
> 
> Can anybody give me a hint where to extend this functionality in CXF itself?
> 
> Thanks
> Oli
> 
> ________________________________________
> Von: Oliver Wulff [owulff@talend.com]
> Gesendet: Mittwoch, 26. Oktober 2011 09:10
> Bis: users@cxf.apache.org
> Betreff: AW: Proxy object used in multi threaded case
> 
> Hi there
> 
> >> The SecureConv and IssuedToken interceptors current "sync" on the
> >> client
> >> object to make sure this case works.   It definitely can be a
> >> performance issue though.
> 
> I guess you mean this:
> 
>      STSClient client = STSUtils.getClient(message, "sts", itok);
>                         AddressingProperties maps =
>                             (AddressingProperties)message
>                                
> .get("javax.xml.ws.addressing.context.outbound"); if (maps == null) {
>                             maps = (AddressingProperties)message
>                                 .get("javax.xml.ws.addressing.context");
>                         }
>                         synchronized (client) {
>                             try {
> 
> 
> I was thinking of using Apache Commons Pool for the proxy objects. But
> before starting, I wanted to double check whether there are better ways
> thus I could contribute the enhancements back to the community. Maybe we
> could introduce a jaxws property for jaxws:client whether pooling should be
> used or not.
> 
> What is the best place to hook this functionality in (ClientFactoryBean,
> ClientProxyFactoryBean or in the ClientProxy thus it works to inject the
> proxy object in your impl class)?
> 
> Thanks
> Oli
> ________________________________________
> Von: Aki Yoshida [elakito@googlemail.com]
> Gesendet: Mittwoch, 19. Oktober 2011 23:57
> Bis: users@cxf.apache.org
> Betreff: Re: Proxy object used in multi threaded case
> 
> 2011/10/19 Aki Yoshida <el...@googlemail.com>:
> > 2011/10/19 Daniel Kulp <dk...@apache.org>:
> >> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
> >>> Hi guys
> >>> 
> >>> I've got a question with respect to a deployment of CXF in an
> >>> intermediary scenario. The service implementation of the
> >>> intermediary injects the proxy instance for the target service it
> >>> will call. Of course, this is a multi threaded environment where
> >>> the service implementation gets the current user as part of the
> >>> incoming message (not ws-security).
> >>> 
> >>> The target service expects to get a security token issued by the
> >>> STS. The username is expected to be set for the proxy and the
> >>> WSSUsernameCallbackHandler is configured to get the user from there.
> >>> 
> >>> Here a snippet of the configuration:
> >>>    <jaxws:client
> >>> 
> >>> name="{http://www.example.org/contract/DoubleIt}DoubleItTransportION
> >>> ABSTPor t" createdFromAPI="true"> <jaxws:properties>
> >>> 
> >>>            <entry key="ws-security.sts.client">
> >>>            
> >>>                <bean
> >>>                class="org.apache.cxf.ws.security.tru
> >>>                st.STSClient">>>>                
> >>>                    <constructor-arg ref="cxf"/>
> >>>                    <property name="onBehalfOf"
> >>> 
> >>> ref="delegationCallbackHandler" />
> >>> 
> >>> 
> >>> The implementation of the intermediary service gets the
> >>> BindingProvider and adds the username like this:
> >>> 
> >>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME_PRO
> >>> PERTY, "myuser)
> >>> 
> >>> Has the request context the scope of the current thread or is it
> >>> tight to the proxy instance.
> >> 
> >> This is answered in the FAQ:
> >> 
> >> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
> >> 
> >>> If latter, an intermediary must create a new proxy per
> >>> request. If the former, what is the scope of the STSClient instance?
> >> 
> >> Per proxy.
> > 
> > If your service implementation is using your proxy and the number of
> > actively used configurations is small, you can pool (or cache) your
> > proxy instances in your service so that you don't need to create a new
> > proxy per call.
> > 
> > For other cases where there is no choice and there is only one proxy
> > instance, it would probably be nice if CXF can introduce an option to
> > make the request/response context objects thread-local. But this may
> > be more complicated and may have some adverse effect.
> 
> I didn't see Dan's faq reference explaining that this thread-local
> option is already provided.
> so, please ignore my comment.
> 
> regards, aki
> 
> > regards, aki
> > 
> >>> If
> >>> there are several requests coming in, the proxy instance is global,
> >>> the
> >>> request context is correlated with the thread (assumption) it might
> >>> not
> >>> work because there is only one STSClient instance.
> >> 
> >> The SecureConv and IssuedToken interceptors current "sync" on the
> >> client
> >> object to make sure this case works.   It definitely can be a
> >> performance issue though.
> >> 
> >> 
> >> --
> >> Daniel Kulp
> >> dkulp@apache.org
> >> http://dankulp.com/blog
> >> Talend - http://www.talend.com
-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

AW: Proxy object used in multi threaded case

Posted by Oliver Wulff <ow...@talend.com>.
Maybe one other point to consider is the way how the IssuedTokenInterceptorProvider handles the TokenStore...

    static final TokenStore getTokenStore(Message message) {
        EndpointInfo info = message.getExchange().get(Endpoint.class).getEndpointInfo();
        synchronized (info) {
            TokenStore tokenStore = (TokenStore)message.getContextualProperty(TokenStore.class.getName());
            if (tokenStore == null) {
                tokenStore = (TokenStore)info.getProperty(TokenStore.class.getName());
            }
            if (tokenStore == null) {
                tokenStore = new MemoryTokenStore();
                info.setProperty(TokenStore.class.getName(), tokenStore);
            }
            return tokenStore;
        }
    }

The TokenStore is tight to the proxy object / exchange object (CXF client) which means if there is a pool of client objects I'd like to avoid that each uses its own TokenStore.

IMHO, the TokenStore should be global (tight to the bus) and get at invocation time a client object of a pool for performance reasons.

Thanks
Oli
________________________________________
Von: Oliver Wulff [owulff@talend.com]
Gesendet: Freitag, 18. November 2011 09:00
Bis: users@cxf.apache.org
Betreff: AW: Proxy object used in multi threaded case

Can anybody give me a hint where to extend this functionality in CXF itself?

Thanks
Oli

________________________________________
Von: Oliver Wulff [owulff@talend.com]
Gesendet: Mittwoch, 26. Oktober 2011 09:10
Bis: users@cxf.apache.org
Betreff: AW: Proxy object used in multi threaded case

Hi there

>>>
>> The SecureConv and IssuedToken interceptors current "sync" on the client
>> object to make sure this case works.   It definitely can be a performance
>> issue though.
>>>

I guess you mean this:

     STSClient client = STSUtils.getClient(message, "sts", itok);
                        AddressingProperties maps =
                            (AddressingProperties)message
                                .get("javax.xml.ws.addressing.context.outbound");
                        if (maps == null) {
                            maps = (AddressingProperties)message
                                .get("javax.xml.ws.addressing.context");
                        }
                        synchronized (client) {
                            try {


I was thinking of using Apache Commons Pool for the proxy objects. But before starting, I wanted to double check whether there are better ways thus I could contribute the enhancements back to the community. Maybe we could introduce a jaxws property for jaxws:client whether pooling should be used or not.

What is the best place to hook this functionality in (ClientFactoryBean, ClientProxyFactoryBean or in the ClientProxy thus it works to inject the proxy object in your impl class)?

Thanks
Oli
________________________________________
Von: Aki Yoshida [elakito@googlemail.com]
Gesendet: Mittwoch, 19. Oktober 2011 23:57
Bis: users@cxf.apache.org
Betreff: Re: Proxy object used in multi threaded case

2011/10/19 Aki Yoshida <el...@googlemail.com>:
> 2011/10/19 Daniel Kulp <dk...@apache.org>:
>> On Wednesday, October 19, 2011 11:00:51 AM Oliver Wulff wrote:
>>> Hi guys
>>>
>>> I've got a question with respect to a deployment of CXF in an intermediary
>>> scenario. The service implementation of the intermediary injects the proxy
>>> instance for the target service it will call. Of course, this is a multi
>>> threaded environment where the service implementation gets the current user
>>> as part of the incoming message (not ws-security).
>>>
>>> The target service expects to get a security token issued by the STS. The
>>> username is expected to be set for the proxy and the
>>> WSSUsernameCallbackHandler is configured to get the user from there.
>>>
>>> Here a snippet of the configuration:
>>>
>>>    <jaxws:client
>>> name="{http://www.example.org/contract/DoubleIt}DoubleItTransportIONABSTPor
>>> t" createdFromAPI="true"> <jaxws:properties>
>>>            <entry key="ws-security.sts.client">
>>>                <bean class="org.apache.cxf.ws.security.trust.STSClient">
>>>                    <constructor-arg ref="cxf"/>
>>>                    <property name="onBehalfOf"
>>> ref="delegationCallbackHandler" />
>>>
>>>
>>> The implementation of the intermediary service gets the BindingProvider and
>>> adds the username like this:
>>>
>>> BindingProvider.getRequestcontext().put(BindingProvider.USERNAME_PROPERTY,
>>> "myuser)
>>>
>>> Has the request context the scope of the current thread or is it tight to
>>> the proxy instance.
>>
>>
>> This is answered in the FAQ:
>>
>> http://cxf.apache.org/faq#FAQ-AreJAXWSclientproxiesthreadsafe%3F
>>
>>
>>> If latter, an intermediary must create a new proxy per
>>> request. If the former, what is the scope of the STSClient instance?
>>
>> Per proxy.
>
> If your service implementation is using your proxy and the number of
> actively used configurations is small, you can pool (or cache) your
> proxy instances in your service so that you don't need to create a new
> proxy per call.
>
> For other cases where there is no choice and there is only one proxy
> instance, it would probably be nice if CXF can introduce an option to
> make the request/response context objects thread-local. But this may
> be more complicated and may have some adverse effect.
>

I didn't see Dan's faq reference explaining that this thread-local
option is already provided.
so, please ignore my comment.

regards, aki

> regards, aki
>
>>
>>> If
>>> there are several requests coming in, the proxy instance is global, the
>>> request context is correlated with the thread (assumption) it might not
>>> work because there is only one STSClient instance.
>>
>> The SecureConv and IssuedToken interceptors current "sync" on the client
>> object to make sure this case works.   It definitely can be a performance
>> issue though.
>>
>>
>> --
>> Daniel Kulp
>> dkulp@apache.org
>> http://dankulp.com/blog
>> Talend - http://www.talend.com
>>
>