Azure Session Table stays empty in AspProvider's TableStorageSessionStateProvider

301 views Asked by At

We have a Web Role which used to run in a single instance for some time. To cope with higher loads (and to get a better SLA) we're currently migrating the role to support multiple instances.

The role uses Forms Authentication (with a custom membership provider), and our understanding was that we would have to enable some sort of shared session state between the instances, so if a user signs in on instance 1 and gets his .ASPXAUTH cookie, then instance 2 knows about this cookie.

We did that, and currently the role is running on two instances, and everything works well. We tested that a user stays signed in, even if his request is processed on the other instance than the one on which he signed in. If the user doesn't sign in, access is denied.

We also checked whether the TableStorageSessionStateProvider created a table in the Azure Table Storage account, and indeed, there is a table Sessions with PartitionKey, RowKey and Timestamp columns.

But, to our astonishment, the Sessions table always stays empty. No matter how many users are signed in, there is no data in the table.

How can these instances communicate, if not through the Sessions table?

1

There are 1 answers

1
Sandrino Di Mattia On BEST ANSWER

You're mixing up two different things here: Authentication and Session State.

It's true that, in order to use Session State with multiple instances, you need a shared store (InProc won't work). In that case TableStorageSessionStateProvider would work since all instances have access to the session data stored here. Session state is used when you store something in the current session of the user, like a shopping cart. And you would call it like this: Session["UserShoppingCart"] = shoppingCart;.

But what you're describing in your question has nothing to do with the Session State, it's all about Forms Authentication. When you authenticate on instance 1, you'll get a ticket in return (stored in the .ASPXAUTH cookie). This ticket is encrypted and signed and contains basic information like your username, expiration, custom user data, ...

Now that you have multiple instances it could be that the next request lands you on instance 2. And I think your question was, how do the instances communicate? Well, they don't. Whenever the request starts, before it reaches your page or your controller, the FormsAuthenticationHttpModule kicks in and looks for the .ASPXAUTH cookie. It checks the signature, decrypts it and then fills the HttpContext.Current.User with the information from the cookie (the ticket).

The only link between the instances is the machineKey (used for encypting/decrypting/signing/validating the cookie). Whenever you deploy multiple instances in Windows Azure, the Fabric Controller makes sure all instances get the same machineKey. This way, instance 2 will be able to decrypt and validate the ticket encryped and signed by instance 1.