Setting the Login Token Expiration Correctly for SharePoint 2010 SAML Claims Users
As I was working on understanding the process for expiring login cookies recently, I found what seemed like a pretty big problem. For SAML claims users, once they got their login cookie from ADFS, they would never seem to time out. Meaning they could close the browser, and several minutes or even hours later open the browser again and just navigate directly to the site without having to reauthenticate to ADFS. In addition the Office 2010 client applications worked the same way. I finally figured out the multiple pieces that were causing that and so I’m documenting them here.
First a really, really brief background. When you navigate to a SharePoint site secured with SAML claims the first time, it will redirect you to get authenticated and get your claims. Your SAML identity provider (a.k.a. IP-STS) does all that and redirects you back to SharePoint. When you come back into SharePoint we create a FedAuth cookie and that’s how we know you’ve been authenticated. To make for smoother end user experience we write the FedAuth cookie value to the local cookies folder. On subsequent requests for that site, if we find a valid FedAuth cookie for the site we’ll just read the cookie and take you right to the SharePoint content without authenticating again. This can be a bit of a jolt to those of you who are used to ADFS 1.x and SharePoint 2007, because with them all Web SSO cookies were session based so we didn’t save them to disk. When you closed your browser for instance, the cookie went away so you had to reauthenticate each time you closed and opened your browser. That is not the case with SharePoint 2010.
UPDATE #1: We found a change that can be made to the SharePoint STS to make it work with session cookies again, as it did in SharePoint 2007. This PowerShell will make the change:
$sts = Get-SPSecurityTokenServiceConfig
$sts.UseSessionCookies = $true
After doing this you will see that there is no longer a FedAuth cookie written to disk. To change things back to the default behavior just reverse your steps:
$sts.UseSessionCookies = $false
So, how do we configure this behavior to get a SAML token with a nice manageable lifetime? Here are the things you need to look at:
- The TokenLifetime property can be set per relying party in ADFS. Unfortunately it seems to only be settable at the time you create the relying party. This is a bit of a problem because that means the default behavior is that once you get a cookie you’re good to go for a really, really long time (I haven’t actually tested to see how long it’s good for).
UPDATE #2: Rich Harrison was good enough to provide this nugget for updating the TokenLifetime in ADFS for the relying party:
Set-ADFSRelyingPartyTrust -TargetName "SPS 2010 ADFS" -TokenLifetime 5
where "SPS 2010 ADFS" is the name of the Relying Party Trust entity in AD FS 2.0.
So, if you want to set the TokenLifetime of the relying party in ADFS at creation time, you need to do so using PowerShell. Here’s the little one line script I used to create my relying party:
Add-ADFSRelyingPartyTrust -Name "FC1" -Identifier "https://fc1/_trust/" -WsFedEndpoint "https://fc1/_trust/" -TokenLifetime 2 -SignatureAlgorithm http://www.w3.org/2000/09/xmldsig#rsa-sha1
After creating the relying party this way you need to manually:
- Add the realm to the list of identifiers (i.e. urn:sharepoint:foo)
- Add an Issuance Authorization Rule to permit access to all users
- Add an Issue Transform Rule to send over email address and roles
- If you just try and login now you will likely find that after you authenticate to ADFS, you’ll get caught up in this endless loop where you go back and forth between SharePoint and ADFS. If you look at the traffic in Fiddler it turns out that you are authenticating successfully to ADFS, you’re coming back to SharePoint and it is successfully issuing the FedAuth cookie, it redirects you to /_layouts/authenticate.aspx on the SharePoint site which clears out the FedAuth cookie and redirects you back to the ADFS site. You basically ping pong back and forth until ADFS stops it and gives you an error message along the lines of “The same client browser session has made ‘6’ requests in the last ‘12’ seconds.”. It turns out that this actually makes sense. That’s because the default LogonTokenCacheExpirationWindow for the SharePoint STS is 10 minutes. In this case when I created my relying party I set the token lifetime in ADFS to be 2 minutes, so as soon as it authenticated it knew the cookie was good for less time than the LogonTokenCacheExpirationWindow value, so it went back to ADFS to authenticate again. And so it went, back and forth. So to fix that part of you just need to change the LogonTokenCacheExpirationWindow to be less than the SAML TokenLifetime, and then you can log into the site. Here’s an example of setting the LogonTokenCacheExpirationWindow in SharePoint:
$sts = Get-SPSecurityTokenServiceConfig
$sts.LogonTokenCacheExpirationWindow = (New-TimeSpan –minutes 1)
Now, once you configure these settings correctly the login expiration for SAML users works correctly. I can open and close my browser window and continue to get back into the site without being redirected back to SharePoint for 2 minutes. After that time though it correctly makes me reauthenticate to ADFS.