7

I'm trying to implement sliding session expiration. I'm using Windows Azure ACS, .Net 4.5, WIF. When I first receive the token, what I'm doing is setting its default expiration time to 2 hours and write that token into cookie as shown in the code below:

internal void SetSession(ClaimsPrincipal principal)
{
    var sessionToken = new SessionSecurityToken(principal, TimeSpan.FromMinutes(120));
    FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
    Thread.CurrentPrincipal = principal;
}

At this time, if I check the ValidFrom and ValidTo properties of the sessionToken variable, I get proper values as shown in the screenshot below:

enter image description here

Now to implement sliding session expiration, I am handling SessionAuthenticationModule_SessionSecurityTokenReceived event in my Global.asax file as shown below:

    void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
    {
        var sessionToken = e.SessionToken;
    }

However when I check the ValidFrom and ValidTo properties of the token, it's not what I set when I was writing the token as the cookie as shown in the screenshot below:

enter image description here

Not sure why this is happening. Can anybody please explain what I'm doing wrong.

UPDATE:

Here's one interesting thing I noticed. The way I've implemented sliding session is that I check token's ValidTo property and compare that with current date/time (in UTC). If the difference is less than 5 minutes, I increase the ValidTo time by 2 hours and reissue the cookie as shown in the code below:

    void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
    {
        var sessionToken = e.SessionToken;
        var currentDateTime = DateTime.UtcNow.Ticks;
        var sessionExpirationDateTime = sessionToken.ValidTo.Ticks;
        if (sessionExpirationDateTime >= currentDateTime)
        {
            var renewTokenWindow = 5 * 60 * 1000;//5 minutes
            TimeSpan ts = new TimeSpan(sessionExpirationDateTime - currentDateTime);
            if (ts.TotalMilliseconds < renewTokenWindow)
            {
                var newSessionTokenExpiry = sessionToken.ValidTo.AddMinutes(120);
                //Renew token
                SessionAuthenticationModule sam = sender as SessionAuthenticationModule;
                var newSessionToken = sam.CreateSessionSecurityToken(sessionToken.ClaimsPrincipal, sessionToken.Context, sessionToken.ValidFrom, newSessionTokenExpiry, sessionToken.IsPersistent);
                e.SessionToken = newSessionToken;
                e.ReissueCookie = true;
            }
        }
    }

Now after that if I check the value of ValidTo property in subsequent requests, it is actually honoring the value I'm setting as shown below. And this value gets persisted request after request i.e. once I reissue the token, everything works well.

enter image description here

Gaurav Mantri
  • 128,066
  • 12
  • 206
  • 241

1 Answers1

1

Thinktecture IdentityModel has an implementation, so you can either reference the package via NuGet or you can just copy the source code:

http://brockallen.com/2013/02/17/sliding-sessions-in-wif-with-the-session-authentication-module-sam-and-thinktecture-identitymodel/

Brock Allen
  • 7,385
  • 19
  • 24
  • Thanks Brock. However I still don't understand why `ValidTo` value is not set to a value I wanted to. Is it a bug with WIF or I'm doing something incorrect? – Gaurav Mantri Jul 28 '13 at 17:19
  • 1
    Hi Brock / Gaurav - Did you manage to figure out why the `ValidTo` value was not being set correctly? – Mike Jan 24 '14 at 11:09
  • 1
    Sorry ... I should have updated the answer long time back. Essentially the default token expiry is set in Windows Azure ACS portal. Whatever value is set there is picked the very first time. HTH. – Gaurav Mantri Jan 24 '14 at 11:12