Skip to content

Sliding sessions in WIF with the session authentication module (SAM) and Thinktecture IdentityModel

February 17, 2013

Session lifetime with WIF’s SAM (session authentication module), by default, is fixed, meaning that the session ends when the token lifetime ends. The logic to determine the session duration (and how to change it) was mentioned here. There is no automatic support for sliding sessions in WIF but it’s possible by handling the SAM’s SessionSecurityTokenReceived event which, when handled in global.asax, typically looks like this:

void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
{
    SessionAuthenticationModule sam = FederatedAuthentication.SessionAuthenticationModule;

    var token = e.SessionToken;
    var duration = token.ValidTo.Subtract(token.ValidFrom);
    if (duration <= TimeSpan.Zero) return;

    var diff = token.ValidTo.Add(sam.FederationConfiguration.IdentityConfiguration.MaxClockSkew).Subtract(DateTime.UtcNow);
    if (diff <= TimeSpan.Zero) return;

    var halfWay = duration.TotalMinutes / 2;
    var timeLeft = diff.TotalMinutes;
    if (timeLeft <= halfWay)
    {
        e.ReissueCookie = true;
        e.SessionToken =
            new SessionSecurityToken(
                token.ClaimsPrincipal,
                token.Context,
                DateTime.UtcNow,
                DateTime.UtcNow.Add(duration))
            {
                IsPersistent = token.IsPersistent,
                IsReferenceMode = token.IsReferenceMode
            };
    }
}

The logic in this event handler will renew the session cookie if the duration remaining is less than half of the total session duration (much like forms authentication). For example, if the session duration is 30 minutes and the user has 15 minutes or less in the session, the session will be renewed. The above code, when issuing a new session security token, also honors some of the other details of session tokens including dealing with the allowable clock skew and preserving the prior token’s flags.

While it’s possible and fairly simply to include the above code in each of your projects if you’d like sliding session, it’s tedious. As such, this feature was added to the Thinktecture IdentityModel security library. It does need to be called from Init in global.asax, but it’s a one-liner:

public override void Init()
{
    PassiveModuleConfiguration.EnableSlidingSessionExpirations();
}

HTH

11 Comments leave one →
  1. Jonathan permalink
    February 20, 2013 8:30 am

    I think that your sliding expiration is not quite right and the ValidTo will increase with the clock skew (5 minutes by default) every time it is renewed. The validTo parameter in the CreateSessionSecurityToken should just be DateTime.UtcNow.Add(token.ValidTo.Subtract(token.ValidFrom)).

    HTH

    • February 20, 2013 8:58 am

      Ah yes — good catch. I was overloading the semantics of the duration variable. Thx

    • February 20, 2013 11:07 am

      So the more I think about it, I don’t think I even need the clock skew check on the duration (only on the ValidTo).

      • Tom permalink
        March 26, 2014 5:26 pm

        Hi, I’ve just come to implement this and without the clock skew on the duration the halfway amount isn’t calculated properly. The skew is factored into the session timeout amount, so the half way amount should as well.
        I had a 10 second timeout (for test purposes) which highlighted the issue as the half way point time was 5 seconds, even though the session takes 5 minutes and 5 seconds to timeout.

        • March 26, 2014 5:30 pm

          So the renewal was happening at 5 seconds, not 2.5 mins? I guess I don’t see it as crucial for the sliding time to be at exactly 1/2 the session time, especially when normally the session is 1 hour to 10 hours, normally. *shrug*

          • Tom permalink
            March 27, 2014 5:31 am

            2 1/2 seconds, so it just wasn’t being hit, because the chances of you hitting the server in that window are pretty slim.
            Fair enough comment on it not needing to be exact, and I only hit the issue as I had a ridiculously short timeout window to test the functionality. We do have short session windows though (lowest is 10 minutes), so more likely to be an issue for us, but I’ve just changed it in our applications.
            Thanks for the article, this was very helpful and saved me a lot of pain :-)

          • March 27, 2014 7:46 am

            Glad it helped. If you feel that it’s worthwhile, feel free to submit a pull request for the code on github — that way everyone else can get the update.

            Thx.

  2. RonyK permalink
    February 24, 2014 5:05 am

    After issuing the new security token and setting the cookie accordingly the BootStrapToken serialized to the current claims Identity remains the old one, with the potentially expired token. This causes problems when trying to use the bootstrap context token for different reasons.
    What is the best way to update the bootstrap token with the new issued token?

    *I also posted the question here: http://stackoverflow.com/questions/21984380/updating-bootstrapcontext-with-new-sessionsecuritytoken-when-using-sliding-sessi

    • February 24, 2014 8:10 am

      Please open an issue on the github issue tracker for the project. Thx.

  3. February 23, 2017 3:15 am

    Sliding expiration is a pretty nice thing to have, the algorithm of re-issuing a token only if it is expired half way is pretty smart. The downside of this solution seems to be that it uses sliding expiration IN STEAD OF absolute expiration. Now a token once issued can be extended unlimited. So once an attacker get a hold of a token it can keep on using it to generate new tokens as long as he refreshes it before it expires. This could be considered a serious security issue.

    I would prefer a situation where there is both a sliding expiration (say 1 hour) and an absolute expiration (say 10 hours). This would require storing both the absolute and the sliding expiration times in the token. As the SessionToken only has a single ‘ValidTo’ property you might need to store the absolute expiration time in a custom claim in the principal.

    Any other Idea how to solve this?

Trackbacks

  1. Thinktecture Identity v2 rolling session security token | DL-UAT

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: