9

I am using ADFS 2.0 for quite some time and I understand how things work. I've done dozen of custom RPs, custom STSes as well as using the ADFS as the relying STS.

However, I have a simple requirement which I still fail to fulfill.

I want my users to be forced to relogin after some fixed time. Let's say 1 minute, for test purposes.

First, I've made some corrections at the RPs side. It seems that for unknown reason, the RP retains the session even if the token's validTo points back in time. This contradicts what Vittorio Bertocci says in his book (page 123) where he shows how to perform sliding expiration - he says that "The SessionAuthenticationModule will take care of handling the expired session right after". Well, for me it doesn't, however I have found a trick here http://blogs.planbsoftware.co.nz/?p=521 - take a look at the "if" clause:

        sam.SessionSecurityTokenReceived +=
            ( s, e ) =>
            {
                SessionAuthenticationModule _sam = s as SessionAuthenticationModule;

                DateTime now = DateTime.UtcNow;

                DateTime validFrom = e.SessionToken.ValidFrom;
                DateTime validTo   = e.SessionToken.ValidTo;

                try
                {
                    double halfSpan = ( validTo - validFrom ).TotalSeconds / 2;
                    if ( validTo < now )
                    {
                        _sam.DeleteSessionTokenCookie();
                        e.Cancel = true;
                    }
                }
                catch ( Exception ex )
                {
                    int v = 0;
                }
            };

This trick fixes the issue at the RPs side. When the token is invalid the application clears it out and redirects to the login page.

Now comes the problem. My login page uses the FederatedPassiveSignIn control. When clicked, it redirects the browser to the ADFS.

But ADFS happily creates a new session without any prompt for the user.

I have set the token's lifetime for this RP to 1:

Set-ADFSRelyingPartyTrust -Targetname "myrpname" -TokenLifetime 1

and using Get-ADFSRelyingPartyTrust I can see that it's set to 1 (I even print the token validTo on my page to confirm that this is set correctly).

Then I set ADFS properties with ADFS-SetProperties:

ADFS-SetProperties -SsoLifetime 1
ADFS-SetProperties -ReplyCacheExpirationInterval 1
ADFS-SetProperties -SamlMessageDeliveryWindow 1

but still no luck. I am stuck now.

The scenario works correctly with my custom STS where the validity of the STS session is based on a Forms cookie - if I set the STS's forms cookie timeout to 1, after 1 minute of inactivity within my RP application I am redirected to the login page of my RP which then redirects to the STS which presents its login page.

However, this is not the case with ADFS 2.0. After a minute of inactivity, I am redirected to the login page of my RP which redirects to ADFS's login page which in turn redirects back happily just like the session would be still active within ADFS.

I would like someone to:

(1) take a look at the hack described at the top and explain why an expired token is not automatically rejected and such ugly hack is needed

(2) explain how to properly timeout the session at the ADFS 2.0 side so a request to renew the token is guarded with a login page.

Thanks in advance.

edit

I can confirm that setting all above parameters to 1 minute makes the ADFS session invalid after 5 minutes (or more). That's strage and it seems that either I am making a basic mistake or 5 minutes is the minumum acceptable value.

My (2) from above is now then just to confirm and explain my observation.

Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
  • from my POV the information you provide is not enough to help (although you provide lots of information) because the timeout behaviour depends on the settings of so many differents parts (STS, RP...) and how these are implemented... since you use lots of custom ones one has to speculate heavily :-( – Yahia Feb 05 '12 at 19:34
  • @Yahia: thanks for the interest. You see, there are no custom components there. It is the ADFS 2.0, installed out of the box and WIF used at the RPs side. No room for speculation, in my opinion. – Wiktor Zychla Feb 05 '12 at 20:22
  • Then I assumed that from *I've done dozen of custom RPs, custom STSes as well as using the ADFS as the relying STS* by mistake. – Yahia Feb 05 '12 at 20:29
  • Ok. It was to point out that I am not a newbie in this field and I need a very specific guidance. – Wiktor Zychla Feb 05 '12 at 20:32
  • ok... I currently can't try it but would suggest setting `Freshness` peroperty of `FederatedPassiveSignIn` to 1 and see what happens... – Yahia Feb 05 '12 at 20:48
  • 1
    It could be a right track. Setting it to 1 doesn't help, however according to the docs (http://docs.oasis-open.org/wsfed/federation/v1.2/ws-federation.html), "if specified as “0” it indicates a request for the IP/STS to re-prompt the user for authentication before issuing the token." And guess what, 0 works correctly! I'll reconfirm this tomorrow. – Wiktor Zychla Feb 05 '12 at 22:02
  • nope but I doubt anyone else will provide any other but yet such useful information. if you'd like to take the bounty, please provide a short answer which mentions this `Freshness` parameter. – Wiktor Zychla Feb 07 '12 at 08:32
  • I really had hoped that this would solve it... posted it as an answer. – Yahia Feb 07 '12 at 08:49

3 Answers3

8

As per comments above (joint effort with the OP) the Freshness property on the FederatedPassiveSignIn instance should be set to 0.

According to http://docs.oasis-open.org/wsfed/federation/v1.2/ws-federation.html this indicates for the IP/STS to re-prompt the user for authentication before it issues the token.

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • Thanks again. I've accepted the answer and awarded it my bounty. – Wiktor Zychla Feb 07 '12 at 08:56
  • you are welcome :-) According to [MSDN](http://msdn.microsoft.com/en-us/library/ff650503.aspx) the behaviour seems to be by design - quote: *To ensure a positive user experience, users should have to enter a user name and password only when logging on to a workstation; users should not have to re-enter them multiple times when accessing multiple clients* – Yahia Feb 07 '12 at 09:00
  • That's why I need more experiments with the `TokenLifeTime` and `SsoLifeTime` parameters. It is possible that setting them to 1 yields the incorrect behavior I observe but setting them to, say, 20 minutes will make it behave correctly. I just hope so. – Wiktor Zychla Feb 07 '12 at 09:03
1

You could also try changing ADFS from windows integrated authentication to forms based authentication. You will probably still have to monkey with the freshness property but now your users will have to enter their credentials even if they are on the same network as your AD.

This article explains it pretty simply:

http://social.technet.microsoft.com/wiki/contents/articles/1600.aspx

Ben Tidman
  • 2,129
  • 17
  • 30
0

It's quite strange that setting the TokenLifetime value didn't work . The article in MSDN explains timeout as a straight forward setting - by assigning TokenLifetime value. I'm interested to know whether the setting described in MSDN is correct. If that didn't help, then it's right time to revise that article. Hope that will be a big help to those who are facing this issue.

Karthik
  • 3,075
  • 3
  • 31
  • 61
  • 1
    thanks for that, even if the question is a little bit old. From what I remember, setting the TokenLifetime for 1 minute wasn't a good idea but I also remember that values HIGHER than 5 minutes worked correctly. – Wiktor Zychla Feb 04 '13 at 07:16
  • Thank you for the prompt reply. Certainly this is a useful tip. I will give it a try and confirm if there are any differences. – Karthik Feb 04 '13 at 22:50