On Monday, November 21, 2011 8:40:26 AM Oliver Wulff wrote: > changed subject > ________________________________________ > Von: Oliver Wulff [[email protected]] > Gesendet: Montag, 21. November 2011 09:38 > Bis: Daniel Kulp; [email protected] > Betreff: AW: AW: AW: Proxy object used in multi threaded case > > > 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?
Likely yes. > 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(....)? Yea, 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? Yep. The message.get(...) really just checks the message itself. The getContextualProperty call more or less checks several places on a defined heiarchy. Message first, endpoint, service, and Bus. I think the Exchange itself is in there as well. For most things, we like to use getContextualProperty as that allows configuring things on the jaxws:endpoint or via API calls or setting things "globally" on the Bus, etc... But in this case (with CACHE_ISSUED_TOKEN_IN_ENDPOINT set to false), it's likely better to call get(...) to get anything that is set just on the message (which is where anything set on the clients RequestContext would be put). ... > 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. If you have the current message (either passed in to the handleMessage for an interceptor or via PhaseInterceptorChain.getCurrentMessage()), you can do: WeakReference<Message> m = message.get(PhaseInterceptorChain.PREVIOUS_MESSAGE); to get the previous message which, for you, should be the incoming message. >From there, you can get the request information and security stuff and such. Dan > > IMHO, I'd go with 2) as I don't need an STS instance. > > Thoughts? > > Thanks > Oli > > ________________________________________ > Von: Daniel Kulp [[email protected]] > Gesendet: Freitag, 18. November 2011 23:06 > Bis: [email protected] > 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 [[email protected]] > > Gesendet: Freitag, 18. November 2011 15:40 > > Bis: [email protected] > > 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.ge > > > tNam > > > 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 [[email protected]] > > > Gesendet: Freitag, 18. November 2011 09:00 > > > Bis: [email protected] > > > 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 [[email protected]] > > > Gesendet: Mittwoch, 26. Oktober 2011 09:10 > > > Bis: [email protected] > > > 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 = > > > > > > (AddressingP > > > rope > > > rties)messag > > > e > > > > > > .get("javax.xml.ws.addressing.context.outbound"); if (maps == null) > > > { > > > > > > maps = > > > (AddressingP > > > rop > > > erties)messa > > > ge > > > > > > .get > > > ("ja > > > vax. > > > xml. > > > ws.a > > > ddre > > > ssin > > > g.co > > > ntex > > > t"); > > > > > > } > > > 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 [[email protected]] > > > Gesendet: Mittwoch, 19. Oktober 2011 23:57 > > > Bis: [email protected] > > > Betreff: Re: Proxy object used in multi threaded case > > > > > > 2011/10/19 Aki Yoshida <[email protected]>: > > > > 2011/10/19 Daniel Kulp <[email protected]>: > > > >> 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}DoubleItTran > > > >>> spor > > > >>> tION > > > >>> ABSTPor t" createdFromAPI="true"> <jaxws:properties> > > > >>> > > > >>> <entry key="ws-security.sts.client"> > > > >>> > > > >>> <bean > > > >>> class="org.apache.cxf.ws.secur > > > >>> ity. > > > >>> 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.USER > > > >>> NAME > > > >>> _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 > > > >> [email protected] > > > >> http://dankulp.com/blog > > > >> Talend - http://www.talend.com > > > > -- > > Daniel Kulp > > [email protected] - http://dankulp.com/blog > > Talend Community Coder - http://coders.talend.com > > -- > Daniel Kulp > [email protected] - http://dankulp.com/blog > Talend Community Coder - http://coders.talend.com -- Daniel Kulp [email protected] - http://dankulp.com/blog Talend Community Coder - http://coders.talend.com
