Skip to main content

WS-Trust, WS-SecureConversation performance issues / Client Caching

6 replies [Last post]
johnhite
Offline
Joined: 2006-07-22
Points: 0

Hello,

I'm having some problems with performance of (or at least confusion around) WS-Trust and WS-SecureConversation. I have a set of around 10 web services that are all used by a web based frontend. My problem is that I'm unable to get good response times from the services without making huge memory sacrifices. I'll explain what I've tried:

The services were all initial secured with WS-Trust and we would create a ws clients from the UI as needed. So, a user would click a button on the web page which generated a request which in turn would create 2 or 3 ws clients and make calls, then return some result back to the UI. This was painfully slow and very CPU intensive.

So, we tried enabling WS-SecureConversation in an attempt to make things better. This had the effect of making things even slower since the ws-client had such a small lifetime (a single request from the UI).

Next we attempted to cache the clients. We implemented a thread local cache of ws clients, so each thread would get a set of clients. We turned on automatic WS-SecureConversation renewal and set the SC Session lifetime to 10 minutes. This made the UI much faster. The first time you clicked something in the UI it might take some time, but after that the response was nearly instant. The only problem now is that we get heap space errors and crashes. If the server was busy, tomcat would create around 30-40 threads, each thread had 10 ws clients, so you end up with 300-400 ws clients each wutg SecureConversation sessions open. This is further complicated by the fact that the SC sessions are not renewed unless a request is made when the session is about to expire. If you attempt to renew after the session is expired, you get an exception, but the memory consumed on the server side from having a SecureConversations session open is not released. (This was with metro 2.0.1. Perhaps this is fixed?)

So, we decided to disable SC automatic renewal and implement our own form of renewal. When we create the ws clients, we put them in a cache with an expiration time. After that expiration time, a new client will be created on the next request instead of returning the cached client. We have a separate thread that periodically goes through all ws clients and calls Close() on the expired ones. We have some occasional strange behavior with this approach, but it more or less works.

I keep thinking there has to be a better way. Am I doing something wrong? Is there anyone else who calls WS-Trust protected services from a web UI?

We've recently updated to Metro 2.2, but that was after we had all this implemented. We were previously on 2.0.1. If anything I described should have been fixed in 2.2, please let me know.

Thanks,
John

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Glen Mazza

Incidentally, aren't the clients that you're caching tied to a
particular user (is your authentication per-user or is it just for the
webapp across all users?) If you're reusing the clients, if User 1
authenticates via WS-Trust & WS-SecConv, the client will have User 1's
security context token, but if the next call is from User 2, wouldn't he
end up reusing User 1's client with User 1's (and not User 2's) token?

I believe CXF has an option that allows the clients to be thread-safe
(although via the JAX-WS spec, they're not required to be), you might
wish to ask on their mailing list for ideas. You wouldn't need to
maintain clients per-thread then. I don't know if Metro has this
option, however.

Glen

On 08/29/2012 04:02 PM, John Hite wrote:
>
> Hello,
>
> I'm having some problems with performance of (or at least confusion
> around) WS-Trust and WS-SecureConversation. I have a set of around 10
> web services that are all used by a web based frontend. My problem is
> that I'm unable to get good response times from the services without
> making huge memory sacrifices. I'll explain what I've tried:
>
> The services were all initial secured with WS-Trust and we would
> create a ws clients from the UI as needed. So, a user would click a
> button on the web page which generated a request which in turn would
> create 2 or 3 ws clients and make calls, then return some result back
> to the UI. This was painfully slow and very CPU intensive.
>
> So, we tried enabling WS-SecureConversation in an attempt to make
> things better. This had the effect of making things even slower since
> the ws-client had such a small lifetime (a single request from the UI).
>
> Next we attempted to cache the clients. We implemented a thread local
> cache of ws clients, so each thread would get a set of clients. We
> turned on automatic WS-SecureConversation renewal and set the SC
> Session lifetime to 10 minutes. This made the UI much faster. The
> first time you clicked something in the UI it might take some time,
> but after that the response was nearly instant. The only problem now
> is that we get heap space errors and crashes. If the server was busy,
> tomcat would create around 30-40 threads, each thread had 10 ws
> clients, so you end up with 300-400 ws clients each wutg
> SecureConversation sessions open. This is further complicated by the
> fact that the SC sessions are not renewed unless a request is made
> when the session is about to expire. If you attempt to renew after the
> session is expired, you get an exception, but the memory consumed on
> the server side from having a SecureConversations session open is not
> released. (This was with metro 2.0.1. Perhaps this is fixed?)
>
> So, we decided to disable SC automatic renewal and implement our own
> form of renewal. When we create the ws clients, we put them in a cache
> with an expiration time. After that expiration time, a new client will
> be created on the next request instead of returning the cached client.
> We have a separate thread that periodically goes through all ws
> clients and calls Close() on the expired ones. We have some occasional
> strange behavior with this approach, but it more or less works.
>
> I keep thinking there has to be a better way. Am I doing something
> wrong? Is there anyone else who calls WS-Trust protected services from
> a web UI?
>
> We've recently updated to Metro 2.2, but that was after we had all
> this implemented. We were previously on 2.0.1. If anything I described
> should have been fixed in 2.2, please let me know.
>
> Thanks,
>
> John
>

johnhite
Offline
Joined: 2006-07-22
Points: 0

Hi Glen,

Metro uses a callback handler to get the client credentials, and, in my experience, it calls it every time you make a request. So, what we do is, basically, set a thread local variable on the callback with the users credential on every web request. That way, when the thread local port calls the callback, it gets the correct user credential. Perhaps this is not part of the spec, and I've just been relying on Metro specific behavior. Do you happen to know?

Thanks,
John

From: Glen Mazza [mailto:gmazza@talend.com]
Sent: Thursday, August 30, 2012 12:27 PM
To: users@metro.java.net
Subject: Re: WS-Trust, WS-SecureConversation performance issues / Client Caching

Incidentally, aren't the clients that you're caching tied to a particular user (is your authentication per-user or is it just for the webapp across all users?) If you're reusing the clients, if User 1 authenticates via WS-Trust & WS-SecConv, the client will have User 1's security context token, but if the next call is from User 2, wouldn't he end up reusing User 1's client with User 1's (and not User 2's) token?

I believe CXF has an option that allows the clients to be thread-safe (although via the JAX-WS spec, they're not required to be), you might wish to ask on their mailing list for ideas. You wouldn't need to maintain clients per-thread then. I don't know if Metro has this option, however.

Glen

On 08/29/2012 04:02 PM, John Hite wrote:
Hello,

I'm having some problems with performance of (or at least confusion around) WS-Trust and WS-SecureConversation. I have a set of around 10 web services that are all used by a web based frontend. My problem is that I'm unable to get good response times from the services without making huge memory sacrifices. I'll explain what I've tried:

The services were all initial secured with WS-Trust and we would create a ws clients from the UI as needed. So, a user would click a button on the web page which generated a request which in turn would create 2 or 3 ws clients and make calls, then return some result back to the UI. This was painfully slow and very CPU intensive.

So, we tried enabling WS-SecureConversation in an attempt to make things better. This had the effect of making things even slower since the ws-client had such a small lifetime (a single request from the UI).

Next we attempted to cache the clients. We implemented a thread local cache of ws clients, so each thread would get a set of clients. We turned on automatic WS-SecureConversation renewal and set the SC Session lifetime to 10 minutes. This made the UI much faster. The first time you clicked something in the UI it might take some time, but after that the response was nearly instant. The only problem now is that we get heap space errors and crashes. If the server was busy, tomcat would create around 30-40 threads, each thread had 10 ws clients, so you end up with 300-400 ws clients each wutg SecureConversation sessions open. This is further complicated by the fact that the SC sessions are not renewed unless a request is made when the session is about to expire. If you attempt to renew after the session is expired, you get an exception, but the memory consumed on the server side from having a SecureConversations session open is not released. (This was with metro 2.0.1. Perhaps this is fixed?)

So, we decided to disable SC automatic renewal and implement our own form of renewal. When we create the ws clients, we put them in a cache with an expiration time. After that expiration time, a new client will be created on the next request instead of returning the cached client. We have a separate thread that periodically goes through all ws clients and calls Close() on the expired ones. We have some occasional strange behavior with this approach, but it more or less works.

I keep thinking there has to be a better way. Am I doing something wrong? Is there anyone else who calls WS-Trust protected services from a web UI?

We've recently updated to Metro 2.2, but that was after we had all this implemented. We were previously on 2.0.1. If anything I described should have been fixed in 2.2, please let me know.

Thanks,
John

Glen Mazza

Implementation details of that nature are outside the scope of the
JAX-WS and WS-Security specs, so, yes, that would be Metro-specific
functionality.

Glen

On 08/30/2012 01:00 PM, John Hite wrote:
>
> Hi Glen,
>
> Metro uses a callback handler to get the client credentials, and, in
> my experience, it calls it every time you make a request. So, what we
> do is, basically, set a thread local variable on the callback with
> the users credential on every web request. That way, when the thread
> local port calls the callback, it gets the correct user credential.
> Perhaps this is not part of the spec, and I've just been relying on
> Metro specific behavior. Do you happen to know?
>
> Thanks,
>
> John
>
> *From:*Glen Mazza [mailto:gmazza@talend.com]
> *Sent:* Thursday, August 30, 2012 12:27 PM
> *To:* users@metro.java.net
> *Subject:* Re: WS-Trust, WS-SecureConversation performance issues /
> Client Caching
>
> Incidentally, aren't the clients that you're caching tied to a
> particular user (is your authentication per-user or is it just for the
> webapp across all users?) If you're reusing the clients, if User 1
> authenticates via WS-Trust & WS-SecConv, the client will have User 1's
> security context token, but if the next call is from User 2, wouldn't
> he end up reusing User 1's client with User 1's (and not User 2's) token?
>
> I believe CXF has an option that allows the clients to be thread-safe
> (although via the JAX-WS spec, they're not required to be), you might
> wish to ask on their mailing list for ideas. You wouldn't need to
> maintain clients per-thread then. I don't know if Metro has this
> option, however.
>
> Glen
>
> On 08/29/2012 04:02 PM, John Hite wrote:
>
> Hello,
>
> I'm having some problems with performance of (or at least
> confusion around) WS-Trust and WS-SecureConversation. I have a set
> of around 10 web services that are all used by a web based
> frontend. My problem is that I'm unable to get good response times
> from the services without making huge memory sacrifices. I'll
> explain what I've tried:
>
> The services were all initial secured with WS-Trust and we would
> create a ws clients from the UI as needed. So, a user would click
> a button on the web page which generated a request which in turn
> would create 2 or 3 ws clients and make calls, then return some
> result back to the UI. This was painfully slow and very CPU intensive.
>
> So, we tried enabling WS-SecureConversation in an attempt to make
> things better. This had the effect of making things even slower
> since the ws-client had such a small lifetime (a single request
> from the UI).
>
> Next we attempted to cache the clients. We implemented a thread
> local cache of ws clients, so each thread would get a set of
> clients. We turned on automatic WS-SecureConversation renewal and
> set the SC Session lifetime to 10 minutes. This made the UI much
> faster. The first time you clicked something in the UI it might
> take some time, but after that the response was nearly instant.
> The only problem now is that we get heap space errors and crashes.
> If the server was busy, tomcat would create around 30-40 threads,
> each thread had 10 ws clients, so you end up with 300-400 ws
> clients each wutg SecureConversation sessions open. This is
> further complicated by the fact that the SC sessions are not
> renewed unless a request is made when the session is about to
> expire. If you attempt to renew after the session is expired, you
> get an exception, but the memory consumed on the server side from
> having a SecureConversations session open is not released. (This
> was with metro 2.0.1. Perhaps this is fixed?)
>
> So, we decided to disable SC automatic renewal and implement our
> own form of renewal. When we create the ws clients, we put them in
> a cache with an expiration time. After that expiration time, a new
> client will be created on the next request instead of returning
> the cached client. We have a separate thread that periodically
> goes through all ws clients and calls Close() on the expired ones.
> We have some occasional strange behavior with this approach, but
> it more or less works.
>
> I keep thinking there has to be a better way. Am I doing something
> wrong? Is there anyone else who calls WS-Trust protected services
> from a web UI?
>
> We've recently updated to Metro 2.2, but that was after we had all
> this implemented. We were previously on 2.0.1. If anything I
> described should have been fixed in 2.2, please let me know.
>
> Thanks,
>
> John
>

Glen Mazza

Incidentally, it would seem that if you're using WS-SecureConversation
then all communication after the first call for a given user (until the
token times out) would just use the same WS-SecConv
SecurityContextToken. You should be able to map users to SCT's, and,
reusing the same client objects, make the request using the SCT assigned
to the user. (If you're using WS-SecConv, I don't see why Metro is
requesting the client credentials for every request, unless the SCT
keeps timing out.) I.e., instead of caching clients just cache SCT's.
Non-trivial coding, but just an idea. :)

Glen

On 08/30/2012 01:55 PM, Glen Mazza wrote:
> Implementation details of that nature are outside the scope of the
> JAX-WS and WS-Security specs, so, yes, that would be Metro-specific
> functionality.
>
> Glen
>
> On 08/30/2012 01:00 PM, John Hite wrote:
>>
>> Hi Glen,
>>
>> Metro uses a callback handler to get the client credentials, and, in
>> my experience, it calls it every time you make a request. So, what we
>> do is, basically, set a thread local variable on the callback with
>> the users credential on every web request. That way, when the thread
>> local port calls the callback, it gets the correct user credential.
>> Perhaps this is not part of the spec, and I've just been relying on
>> Metro specific behavior. Do you happen to know?
>>
>> Thanks,
>>
>> John
>>
>> *From:*Glen Mazza [mailto:gmazza@talend.com]
>> *Sent:* Thursday, August 30, 2012 12:27 PM
>> *To:* users@metro.java.net
>> *Subject:* Re: WS-Trust, WS-SecureConversation performance issues /
>> Client Caching
>>
>> Incidentally, aren't the clients that you're caching tied to a
>> particular user (is your authentication per-user or is it just for
>> the webapp across all users?) If you're reusing the clients, if User
>> 1 authenticates via WS-Trust & WS-SecConv, the client will have User
>> 1's security context token, but if the next call is from User 2,
>> wouldn't he end up reusing User 1's client with User 1's (and not
>> User 2's) token?
>>
>> I believe CXF has an option that allows the clients to be thread-safe
>> (although via the JAX-WS spec, they're not required to be), you might
>> wish to ask on their mailing list for ideas. You wouldn't need to
>> maintain clients per-thread then. I don't know if Metro has this
>> option, however.
>>
>> Glen
>>
>> On 08/29/2012 04:02 PM, John Hite wrote:
>>
>> Hello,
>>
>> I'm having some problems with performance of (or at least
>> confusion around) WS-Trust and WS-SecureConversation. I have a
>> set of around 10 web services that are all used by a web based
>> frontend. My problem is that I'm unable to get good response
>> times from the services without making huge memory sacrifices.
>> I'll explain what I've tried:
>>
>> The services were all initial secured with WS-Trust and we would
>> create a ws clients from the UI as needed. So, a user would click
>> a button on the web page which generated a request which in turn
>> would create 2 or 3 ws clients and make calls, then return some
>> result back to the UI. This was painfully slow and very CPU
>> intensive.
>>
>> So, we tried enabling WS-SecureConversation in an attempt to make
>> things better. This had the effect of making things even slower
>> since the ws-client had such a small lifetime (a single request
>> from the UI).
>>
>> Next we attempted to cache the clients. We implemented a thread
>> local cache of ws clients, so each thread would get a set of
>> clients. We turned on automatic WS-SecureConversation renewal and
>> set the SC Session lifetime to 10 minutes. This made the UI much
>> faster. The first time you clicked something in the UI it might
>> take some time, but after that the response was nearly instant.
>> The only problem now is that we get heap space errors and
>> crashes. If the server was busy, tomcat would create around 30-40
>> threads, each thread had 10 ws clients, so you end up with
>> 300-400 ws clients each wutg SecureConversation sessions open.
>> This is further complicated by the fact that the SC sessions are
>> not renewed unless a request is made when the session is about to
>> expire. If you attempt to renew after the session is expired, you
>> get an exception, but the memory consumed on the server side from
>> having a SecureConversations session open is not released. (This
>> was with metro 2.0.1. Perhaps this is fixed?)
>>
>> So, we decided to disable SC automatic renewal and implement our
>> own form of renewal. When we create the ws clients, we put them
>> in a cache with an expiration time. After that expiration time, a
>> new client will be created on the next request instead of
>> returning the cached client. We have a separate thread that
>> periodically goes through all ws clients and calls Close() on the
>> expired ones. We have some occasional strange behavior with this
>> approach, but it more or less works.
>>
>> I keep thinking there has to be a better way. Am I doing
>> something wrong? Is there anyone else who calls WS-Trust
>> protected services from a web UI?
>>
>> We've recently updated to Metro 2.2, but that was after we had
>> all this implemented. We were previously on 2.0.1. If anything I
>> described should have been fixed in 2.2, please let me know.
>>
>> Thanks,
>>
>> John
>>
>

johnhite
Offline
Joined: 2006-07-22
Points: 0

That's an interesting idea. Do you know if metro exposes the SCT somehow? Can I take the SCT from one client and set it on another? Can I duplicate the SCT and us it on multiple clients at the same time? The browser will make multiple, simultaneous requests.

About metro requesting client credentials every time, you are correct. I am actually caching per user per thread, which is probably why my memory usage is so high.

Thanks,
John

From: Glen Mazza [mailto:gmazza@talend.com]
Sent: Thursday, August 30, 2012 3:44 PM
To: users@metro.java.net
Subject: Re: WS-Trust, WS-SecureConversation performance issues / Client Caching

Incidentally, it would seem that if you're using WS-SecureConversation then all communication after the first call for a given user (until the token times out) would just use the same WS-SecConv SecurityContextToken. You should be able to map users to SCT's, and, reusing the same client objects, make the request using the SCT assigned to the user. (If you're using WS-SecConv, I don't see why Metro is requesting the client credentials for every request, unless the SCT keeps timing out.) I.e., instead of caching clients just cache SCT's. Non-trivial coding, but just an idea. :)

Glen

On 08/30/2012 01:55 PM, Glen Mazza wrote:
Implementation details of that nature are outside the scope of the JAX-WS and WS-Security specs, so, yes, that would be Metro-specific functionality.

Glen

On 08/30/2012 01:00 PM, John Hite wrote:
Hi Glen,

Metro uses a callback handler to get the client credentials, and, in my experience, it calls it every time you make a request. So, what we do is, basically, set a thread local variable on the callback with the users credential on every web request. That way, when the thread local port calls the callback, it gets the correct user credential. Perhaps this is not part of the spec, and I've just been relying on Metro specific behavior. Do you happen to know?

Thanks,
John

From: Glen Mazza [mailto:gmazza@talend.com]
Sent: Thursday, August 30, 2012 12:27 PM
To: users@metro.java.net
Subject: Re: WS-Trust, WS-SecureConversation performance issues / Client Caching

Incidentally, aren't the clients that you're caching tied to a particular user (is your authentication per-user or is it just for the webapp across all users?) If you're reusing the clients, if User 1 authenticates via WS-Trust & WS-SecConv, the client will have User 1's security context token, but if the next call is from User 2, wouldn't he end up reusing User 1's client with User 1's (and not User 2's) token?

I believe CXF has an option that allows the clients to be thread-safe (although via the JAX-WS spec, they're not required to be), you might wish to ask on their mailing list for ideas. You wouldn't need to maintain clients per-thread then. I don't know if Metro has this option, however.

Glen

On 08/29/2012 04:02 PM, John Hite wrote:
Hello,

I'm having some problems with performance of (or at least confusion around) WS-Trust and WS-SecureConversation. I have a set of around 10 web services that are all used by a web based frontend. My problem is that I'm unable to get good response times from the services without making huge memory sacrifices. I'll explain what I've tried:

The services were all initial secured with WS-Trust and we would create a ws clients from the UI as needed. So, a user would click a button on the web page which generated a request which in turn would create 2 or 3 ws clients and make calls, then return some result back to the UI. This was painfully slow and very CPU intensive.

So, we tried enabling WS-SecureConversation in an attempt to make things better. This had the effect of making things even slower since the ws-client had such a small lifetime (a single request from the UI).

Next we attempted to cache the clients. We implemented a thread local cache of ws clients, so each thread would get a set of clients. We turned on automatic WS-SecureConversation renewal and set the SC Session lifetime to 10 minutes. This made the UI much faster. The first time you clicked something in the UI it might take some time, but after that the response was nearly instant. The only problem now is that we get heap space errors and crashes. If the server was busy, tomcat would create around 30-40 threads, each thread had 10 ws clients, so you end up with 300-400 ws clients each wutg SecureConversation sessions open. This is further complicated by the fact that the SC sessions are not renewed unless a request is made when the session is about to expire. If you attempt to renew after the session is expired, you get an exception, but the memory consumed on the server side from having a SecureConversations session open is not released. (This was with metro 2.0.1. Perhaps this is fixed?)

So, we decided to disable SC automatic renewal and implement our own form of renewal. When we create the ws clients, we put them in a cache with an expiration time. After that expiration time, a new client will be created on the next request instead of returning the cached client. We have a separate thread that periodically goes through all ws clients and calls Close() on the expired ones. We have some occasional strange behavior with this approach, but it more or less works.

I keep thinking there has to be a better way. Am I doing something wrong? Is there anyone else who calls WS-Trust protected services from a web UI?

We've recently updated to Metro 2.2, but that was after we had all this implemented. We were previously on 2.0.1. If anything I described should have been fixed in 2.2, please let me know.

Thanks,
John

Glen Mazza

This is what goes out on the wire during WS-Trust and WS-SecConv w/Metro
for two calls:
https://gist.github.com/3191480. Steps #5-#8 will show the same SCT
bouncing back and forth *without* additional credential requests
needed. It would be nice if you could somehow architect your system so
Metro will do that "same SCT bouncing back and forth" bit for you
automatically when your webapp is making requests.

The above link is referenced on this blog article:
http://www.jroller.com/gmazza/entry/wstrust_soap_call_analysis, which
links back to this one:
http://www.jroller.com/gmazza/entry/metro_sts_tutorial (which has the
code that generated the above SOAP requests).

The above, if it can be done, would not require you to manually grab and
work with the SCT directly. But if you have to, you might be able to
obtain the SCT via JAX-WS handlers
(http://www.jroller.com/gmazza/entry/jaxws_handler_tutorial). I don't
know when Metro adds the security headers to the SOAP requests though,
and manually working with the SCTs might get very complex, especially if
you have to recalculate signatures/do additional encryption, etc. as you
attempt to reuse an SCT.

Glen

On 08/31/2012 09:50 AM, John Hite wrote:
>
> That's an interesting idea. Do you know if metro exposes the SCT
> somehow? Can I take the SCT from one client and set it on another? Can
> I duplicate the SCT and us it on multiple clients at the same time?
> The browser will make multiple, simultaneous requests.
>
> About metro requesting client credentials every time, you are correct.
> I am actually caching per user per thread, which is probably why my
> memory usage is so high.
>
> Thanks,
>
> John
>
> *From:*Glen Mazza [mailto:gmazza@talend.com]
> *Sent:* Thursday, August 30, 2012 3:44 PM
> *To:* users@metro.java.net
> *Subject:* Re: WS-Trust, WS-SecureConversation performance issues /
> Client Caching
>
> Incidentally, it would seem that if you're using WS-SecureConversation
> then all communication after the first call for a given user (until
> the token times out) would just use the same WS-SecConv
> SecurityContextToken. You should be able to map users to SCT's, and,
> reusing the same client objects, make the request using the SCT
> assigned to the user. (If you're using WS-SecConv, I don't see why
> Metro is requesting the client credentials for every request, unless
> the SCT keeps timing out.) I.e., instead of caching clients just
> cache SCT's. Non-trivial coding, but just an idea. :)
>
> Glen
>
> On 08/30/2012 01:55 PM, Glen Mazza wrote:
>
> Implementation details of that nature are outside the scope of the
> JAX-WS and WS-Security specs, so, yes, that would be
> Metro-specific functionality.
>
> Glen
>
> On 08/30/2012 01:00 PM, John Hite wrote:
>
> Hi Glen,
>
> Metro uses a callback handler to get the client credentials,
> and, in my experience, it calls it every time you make a
> request. So, what we do is, basically, set a thread local
> variable on the callback with the users credential on every
> web request. That way, when the thread local port calls the
> callback, it gets the correct user credential. Perhaps this is
> not part of the spec, and I've just been relying on Metro
> specific behavior. Do you happen to know?
>
> Thanks,
>
> John
>
> *From:*Glen Mazza [mailto:gmazza@talend.com]
> *Sent:* Thursday, August 30, 2012 12:27 PM
> *To:* users@metro.java.net
> *Subject:* Re: WS-Trust, WS-SecureConversation performance
> issues / Client Caching
>
> Incidentally, aren't the clients that you're caching tied to a
> particular user (is your authentication per-user or is it just
> for the webapp across all users?) If you're reusing the
> clients, if User 1 authenticates via WS-Trust & WS-SecConv,
> the client will have User 1's security context token, but if
> the next call is from User 2, wouldn't he end up reusing User
> 1's client with User 1's (and not User 2's) token?
>
> I believe CXF has an option that allows the clients to be
> thread-safe (although via the JAX-WS spec, they're not
> required to be), you might wish to ask on their mailing list
> for ideas. You wouldn't need to maintain clients per-thread
> then. I don't know if Metro has this option, however.
>
> Glen
>
> On 08/29/2012 04:02 PM, John Hite wrote:
>
> Hello,
>
> I'm having some problems with performance of (or at least
> confusion around) WS-Trust and WS-SecureConversation. I
> have a set of around 10 web services that are all used by
> a web based frontend. My problem is that I'm unable to get
> good response times from the services without making huge
> memory sacrifices. I'll explain what I've tried:
>
> The services were all initial secured with WS-Trust and we
> would create a ws clients from the UI as needed. So, a
> user would click a button on the web page which generated
> a request which in turn would create 2 or 3 ws clients and
> make calls, then return some result back to the UI. This
> was painfully slow and very CPU intensive.
>
> So, we tried enabling WS-SecureConversation in an attempt
> to make things better. This had the effect of making
> things even slower since the ws-client had such a small
> lifetime (a single request from the UI).
>
> Next we attempted to cache the clients. We implemented a
> thread local cache of ws clients, so each thread would get
> a set of clients. We turned on automatic
> WS-SecureConversation renewal and set the SC Session
> lifetime to 10 minutes. This made the UI much faster. The
> first time you clicked something in the UI it might take
> some time, but after that the response was nearly instant.
> The only problem now is that we get heap space errors and
> crashes. If the server was busy, tomcat would create
> around 30-40 threads, each thread had 10 ws clients, so
> you end up with 300-400 ws clients each wutg
> SecureConversation sessions open. This is further
> complicated by the fact that the SC sessions are not
> renewed unless a request is made when the session is about
> to expire. If you attempt to renew after the session is
> expired, you get an exception, but the memory consumed on
> the server side from having a SecureConversations session
> open is not released. (This was with metro 2.0.1. Perhaps
> this is fixed?)
>
> So, we decided to disable SC automatic renewal and
> implement our own form of renewal. When we create the ws
> clients, we put them in a cache with an expiration time.
> After that expiration time, a new client will be created
> on the next request instead of returning the cached
> client. We have a separate thread that periodically goes
> through all ws clients and calls Close() on the expired
> ones. We have some occasional strange behavior with this
> approach, but it more or less works.
>
> I keep thinking there has to be a better way. Am I doing
> something wrong? Is there anyone else who calls WS-Trust
> protected services from a web UI?
>
> We've recently updated to Metro 2.2, but that was after we
> had all this implemented. We were previously on 2.0.1. If
> anything I described should have been fixed in 2.2, please
> let me know.
>
> Thanks,
>
> John
>

Oliver Wulff

WS-SecureConversation requires message encryption/signature on the message
level which has a performance impact as well.

I have got the same setup where the web services are protected by SAML
tokens issued by an STS. The consuming application is a web application
which is protected by a SAML token (WS-Trust, WS-Federation) as well. The
latter can be implemented with the Apache
Fedizproject. This can
be used for any web services stack.
Fediz caches the SAML token in the session. If you send a soap request to a
web services it requests a new token from the STS onbehalfof the cached one.
There is a complete
exampleavailable
in Fediz which shows the whole setup (web application, web
services, sts, idp). This example only uses a single jaxws proxy instance
and goes to the STS only once per user for the duration of the token
validity. The example is based on CXF. It can be used as a base how to
implement it similar for metro.

HTH

Oli

2012/8/31 Glen Mazza

> This is what goes out on the wire during WS-Trust and WS-SecConv w/Metro
> for two calls:
> https://gist.github.com/3191480. Steps #5-#8 will show the same SCT
> bouncing back and forth *without* additional credential requests needed.
> It would be nice if you could somehow architect your system so Metro will
> do that "same SCT bouncing back and forth" bit for you automatically when
> your webapp is making requests.
>
> The above link is referenced on this blog article:
> http://www.jroller.com/gmazza/entry/wstrust_soap_call_analysis, which
> links back to this one:
> http://www.jroller.com/gmazza/entry/metro_sts_tutorial (which has the
> code that generated the above SOAP requests).
>
> The above, if it can be done, would not require you to manually grab and
> work with the SCT directly. But if you have to, you might be able to
> obtain the SCT via JAX-WS handlers (
> http://www.jroller.com/gmazza/entry/jaxws_handler_tutorial). I don't
> know when Metro adds the security headers to the SOAP requests though, and
> manually working with the SCTs might get very complex, especially if you
> have to recalculate signatures/do additional encryption, etc. as you
> attempt to reuse an SCT.
>
> Glen
>
>
> On 08/31/2012 09:50 AM, John Hite wrote:
>
> That’s an interesting idea. Do you know if metro exposes the SCT
> somehow? Can I take the SCT from one client and set it on another? Can I
> duplicate the SCT and us it on multiple clients at the same time? The
> browser will make multiple, simultaneous requests. ****
>
> ** **
>
> About metro requesting client credentials every time, you are correct. I
> am actually caching per user per thread, which is probably why my memory
> usage is so high.****
>
> ** **
>
> Thanks,****
>
> John****
>
> ** **
>
> *From:* Glen Mazza [mailto:gmazza@talend.com ]
> *Sent:* Thursday, August 30, 2012 3:44 PM
> *To:* users@metro.java.net
> *Subject:* Re: WS-Trust, WS-SecureConversation performance issues /
> Client Caching****
>
> ** **
>
> Incidentally, it would seem that if you're using WS-SecureConversation
> then all communication after the first call for a given user (until the
> token times out) would just use the same WS-SecConv SecurityContextToken.
> You should be able to map users to SCT's, and, reusing the same client
> objects, make the request using the SCT assigned to the user. (If you're
> using WS-SecConv, I don't see why Metro is requesting the client
> credentials for every request, unless the SCT keeps timing out.) I.e.,
> instead of caching clients just cache SCT's. Non-trivial coding, but just
> an idea. :)
>
> Glen
>
> On 08/30/2012 01:55 PM, Glen Mazza wrote:****
>
> Implementation details of that nature are outside the scope of the
> JAX-WS and WS-Security specs, so, yes, that would be Metro-specific
> functionality.
>
> Glen
>
> On 08/30/2012 01:00 PM, John Hite wrote:****
>
> Hi Glen, ****
>
> ****
>
> Metro uses a callback handler to get the client credentials, and, in my
> experience, it calls it every time you make a request. So, what we do is,
> basically, set a thread local variable on the callback with the users
> credential on every web request. That way, when the thread local port calls
> the callback, it gets the correct user credential. Perhaps this is not part
> of the spec, and I’ve just been relying on Metro specific behavior. Do you
> happen to know?****
>
> ****
>
> Thanks,****
>
> John****
>
> ****
>
> *From:* Glen Mazza [mailto:gmazza@talend.com ]
> *Sent:* Thursday, August 30, 2012 12:27 PM
> *To:* users@metro.java.net
> *Subject:* Re: WS-Trust, WS-SecureConversation performance issues /
> Client Caching****
>
> ****
>
> Incidentally, aren't the clients that you're caching tied to a particular
> user (is your authentication per-user or is it just for the webapp across
> all users?) If you're reusing the clients, if User 1 authenticates via
> WS-Trust & WS-SecConv, the client will have User 1's security context
> token, but if the next call is from User 2, wouldn't he end up reusing User
> 1's client with User 1's (and not User 2's) token?
>
> I believe CXF has an option that allows the clients to be thread-safe
> (although via the JAX-WS spec, they're not required to be), you might wish
> to ask on their mailing list for ideas. You wouldn't need to maintain
> clients per-thread then. I don't know if Metro has this option, however.
>
> Glen
>
> On 08/29/2012 04:02 PM, John Hite wrote:****
>
> Hello,****
>
> ****
>
> I’m having some problems with performance of (or at least confusion
> around) WS-Trust and WS-SecureConversation. I have a set of around 10 web
> services that are all used by a web based frontend. My problem is that I’m
> unable to get good response times from the services without making huge
> memory sacrifices. I’ll explain what I’ve tried:****
>
> ****
>
> The services were all initial secured with WS-Trust and we would create a
> ws clients from the UI as needed. So, a user would click a button on the
> web page which generated a request which in turn would create 2 or 3 ws
> clients and make calls, then return some result back to the UI. This was
> painfully slow and very CPU intensive.****
>
> ****
>
> So, we tried enabling WS-SecureConversation in an attempt to make things
> better. This had the effect of making things even slower since the
> ws-client had such a small lifetime (a single request from the UI).****
>
> ****
>
> Next we attempted to cache the clients. We implemented a thread local
> cache of ws clients, so each thread would get a set of clients. We turned
> on automatic WS-SecureConversation renewal and set the SC Session lifetime
> to 10 minutes. This made the UI much faster. The first time you clicked
> something in the UI it might take some time, but after that the response
> was nearly instant. The only problem now is that we get heap space errors
> and crashes. If the server was busy, tomcat would create around 30-40
> threads, each thread had 10 ws clients, so you end up with 300-400 ws
> clients each wutg SecureConversation sessions open. This is further
> complicated by the fact that the SC sessions are not renewed unless a
> request is made when the session is about to expire. If you attempt to
> renew after the session is expired, you get an exception, but the memory
> consumed on the server side from having a SecureConversations session open
> is not released. (This was with metro 2.0.1. Perhaps this is fixed?)****
>
> ****
>
> So, we decided to disable SC automatic renewal and implement our own form
> of renewal. When we create the ws clients, we put them in a cache with an
> expiration time. After that expiration time, a new client will be created
> on the next request instead of returning the cached client. We have a
> separate thread that periodically goes through all ws clients and calls
> Close() on the expired ones. We have some occasional strange behavior with
> this approach, but it more or less works.****
>
> ****
>
> I keep thinking there has to be a better way. Am I doing something wrong?
> Is there anyone else who calls WS-Trust protected services from a web UI?*
> ***
>
> ****
>
> We’ve recently updated to Metro 2.2, but that was after we had all this
> implemented. We were previously on 2.0.1. If anything I described should
> have been fixed in 2.2, please let me know.****
>
> ****
>
> Thanks,****
>
> John****
>
> ****
>
> ****
>
> ** **
>
> ** **
>
>
>