WIF sliding session re-authenticate
Asked Answered
C

1

7

I've implemented sliding sessions in my Relying Party application, as described in Sliding Sessions for WIF 4.5. That works great as far as it goes, but there's one problem that it seems nobody talks about.

As the linked blog post points out, when the RP token expires, the next time make a request the token is re-issued from the STS. Assuming, of course, that the STS session lifetime is longer than the RP's session lifetime, which is almost certainly the case if you're implementing sliding sessions.

In any event, that completely defeats the whole point of sliding sessions.

What nobody seems to talk about is what to do when the RP session expires. What I want is, if the RP session times out (usually because somebody walked away from his desk for 10 minutes), is for my application to redirect to the STS login page where the user can re-authenticate, and then be redirected back to the page I had requested; or perhaps to the page that I was on when I made the request.

I'm almost certain that this is possible, but I have absolutely no idea how it's done.

Here's my code from global.asax:

    private const int InactivityTimeout = 5; // minutes

    void SessionAuthenticationModule_SessionSecurityTokenReceived
        (object sender, SessionSecurityTokenReceivedEventArgs e)
    {
        var now = DateTime.UtcNow;
        var validFrom = e.SessionToken.ValidFrom;
        var validTo = e.SessionToken.ValidTo;
        double halfSpan = (validTo - validFrom).TotalMinutes/2;
        if (validFrom.AddMinutes(halfSpan) < now && now < validTo)
        {
            // add more time
            var sam = sender as SessionAuthenticationModule;

            e.SessionToken = sam.CreateSessionSecurityToken(
                e.SessionToken.ClaimsPrincipal,
                e.SessionToken.Context,
                now,
                now.AddMinutes(InactivityTimeout),
                e.SessionToken.IsPersistent);
            e.ReissueCookie = true;
        }
        else
        {
            // re-authenticate with STS
        }
    }

My questions:

  1. Is the else clause the proper place to put the re-authentication logic?
  2. If so, please provide an example, 'cause I have no idea.
  3. If the answer to #1 is no, then is there a separate event I need to subscribe to that will tell me "Hey, your session security token has expired!"?
Coldiron answered 5/9, 2013 at 16:24 Comment(0)
S
2

I'd recommend you sync the session lifetimes on the STS and the RP(s).

You can set the session lifetime to 10 minutes on the STS and 10 minutes on the RP and use the sliding session approach on the RP. After 10 minutes of inactivity both sessions would expire and the user should be required to re-authenticate.

If you have multiple RPs you could implement a form of keep-alive from the RP to the STS - e.g. load a resource from the STS in every webpage on the RPs. Whenever a page is loaded on an RP, the keep-alive resource would be loaded from the STS - refreshing the STS session. After 10 minutes of inactivity they would both time out and the user would have to re-authenticate.

"A resource from the STS" could mean a web page (Web Forms/MVC) loaded in an invisible iframe. The important thing is that it's a managed handler so the request is handled by ASP.NET.

As for your questions, if you sync the session lifetimes so they time out together:

  1. No, you don't need to add any code in the else clause. If the token is expired, WIF will redirect to the STS.
  2. Just remove the else clause.
  3. Let WIF handle this for you.

For completeness, if you can't sync the session lifetimes you could trigger a federated sign-out when the RP session expires. The following snippet triggers a signout at the configured Issuer (STS). You could put this in the else clause to trigger a signout on the first request after the RP session expires:

using System.IdentityModel.Services; //WIF 4.5

var stsAddress = new Uri(FederatedAuthentication.FederationConfiguration.WsFederationConfiguration.Issuer);
WSFederationAuthenticationModule.FederatedSignOut(stsAddress, null); //Optional replyUrl set to null

Hope that helps!

Sheathbill answered 16/9, 2013 at 19:31 Comment(6)
Thanks for the reply. I don't want to sync the session lifetimes because that would force the user to re-authenticate every 10 minutes. Imagine if you had to do that while you're working in Visual Studio. What I want is for it to work like my Windows machine: my session remains valid as long as I'm using the computer. But if I'm idle for 5 minutes, it locks my workstation and I have to re-authenticate. The federated signout could work, as long as I can be returned to the page where I left off. I'll give that a try.Coldiron
I don't see how the user would have to re-authenticate every 10 minutes when you've implemented sliding sessions on the RP.Sheathbill
If I set the session lifetime to 10 minutes on the STS as you recommended, then the STS token will expire after 10 minutes. The RP can't extend the token's lifetime to longer than the STS token allows. Unless I misunderstood something you wrote?Coldiron
If you set the session security token lifetime in config for the sessionSecurityTokenHandler you cannot extend the session token lifetime beyond the lifetime in the token issued by the STS IIRC. I was pretty sure the sliding session implementation would override this, but I might be remembering this wrong. You are still being redirected to the STS even though you extend the lifetime of the session token on the RP?Sheathbill
@JimMischel I'm wondering if you achieved what you wanted. I'm looking to do the same thing, in the else clause I've put the signout code klings suggested, FederatedSignout... but I keep getting a generic error "Sorry, an error occurred while processing your request.", I'm using Thinktecture IdentityServer.Gemmule
@MohammadSepahvand: The code I posted above, with the addition of the FederatedSignout that klings suggested, worked well in my application. I no longer have access to that code and am no longer using Thinktecture IdentityServer. If you're having trouble, you probably would be best served by posting a question.Coldiron

© 2022 - 2024 — McMap. All rights reserved.