Udostępnij za pośrednictwem


SCT Options - Pinning a client session to a service instance

Most web developers are familiar with one way with maintaining state within a web farm from their ASP days...server affinity.  This was really the only optional available before .NET other than writing your own distributed session management solution for web applications if you wanted to maintain server side session state.  This approach can also be used in the case of SCTs.  Since most web services today are typically accessed via http, this logic is already built into load balancing hardware, and often these balancers will setup affinity for a particular service instance based on such values as client IP address or a cookie value, such as session ID.  A common term used to describe this is "pinning" the session to a server instance.  This may be a perfectly adequate solution for your service, and this is certainly the easiest option to implement.  There is no additional development work required to implement this approach - typically just flip a switch in your load balancer, and your off to the races.  The advantages of this approach are:

  • Easiest to implement - no code required
  • The most performant solution (assuming that it doesn't introduce significant load imbalance issues that are possible when pinning occurs)
  • Simplest solution to support operationally
  • Supports all base token types efficiently (more on this below)

The disadvantages of this solution are:

  • Not resielent to server failures.  Since the client is pinned to a particular instance, if the server goes down, the SCT is no longer valid.  If the message subsequently gets rerouted to an available server, it will be rejected.  This could be compensated for by logic in a smart client side proxy.
  • Can introduce imbalances in loading - this is a typical problem with pinning a session to a particular instance
  • Reliant upon some type of session affinity management.  This is typical available with http load balancers, but may not be as likely of a feature for other load balancing solutions.
  • This is a point-to-point approach.  Messages transiting multiple hops won't have an http connection directly between the client and service.

One of the advantages mentioned above is supports all types of base tokens efficiently.  The limitiation with the other two approaches mentioned that I will cover in the future is that they require the base token information to be serialized.  Since the WSE SecurityToken class is not serialable, no derived class can not be serializable.  There is an out...you should typically at least be able to retrieve the XML representation of a token with GetXml and LoadXml, but this adds significant additional memory and processing costs over binary serialization for the cached token.  A technique to mitigate this cost that will be covered later is to cache the token locally.  Therefore the deserialization only needs to occur if the token is not in the local cache - which means only once per token per service instance (assuming that the token doesn't get flushed from a full cache).

For a high reliability system, this approach would not be the best choice.  While choosing the simplest solution that meets your needs is almost always the best choice, I am bothered by the fact that this relies on out-of-band information for session affinity and requires point to point communications that seesms to violate the spirit of messaging within SOA.  But then I think maybe I'm being too much of a purist...

Tomorrow I'll start covering the distributed cache approach, where I'll start digging into some code samples.

Comments

  • Anonymous
    August 19, 2004
    The primary use of an SCT is to cache the credentials of the other endpoint of the conversation. Although there would be an additional expense to "renegotiate" the credentials, can there be a way for one endpoint to say "oops, I lost your ticket" and then ask for valid ID?

    There would be several benefits:
    * The credential process would be recoverable in the case of a service failure.
    * Endpoints would not be required to cache the credentials indefinitely (where "indefinitely" means for the span of the conversation, and a conversation can be long-running, e.g. an Ent service)

    I suppose that if an endpoint elected to use an SCT rather than reauthenticating for every message, it should be prepared to manage the token. A long-running converstaion is going to have some state, or it would just be a one-time request, so the endpoints should probably be prepared to manage the SCT with whatever state mechanism they are currently using.

    So doesn't this imply that you should manage your SCT with your service state?

  • Anonymous
    August 19, 2004
    Your absolutely right. This is an approach that can be used and what I meant to allude to with the smart client side proxy in the disadvantage listed. The recovery logic for this case would all be client side. The client would need to cache the original security token used to establish the secure conversation which is stateless, catch the trust fault that will be thrown by the service instance failed over to, re-negotiate the SCT using the original security token with the new service instance, and then re-submit the service request. The SCT will still only be valid for one service instance, so you would still want to use a session affinity mechanism.

    The service itself still isn't resilent to failure, and the client side logic becomes a bit more complicated. However if you control both the service and client side of the implementation, then this should be a consideration. I have not actually tried this one out, so I'm not sure how easy it would be to generalize a solution for the client proxy - my gut feel is that it may be difficult. I'll have to give it a try after I get through the other two alternatives.