SharePoint 2010 Session Management
We've been doing a fair bit of research lately on how better to deal with sessions on a forms-based authentication site. By default SharePoint creates a fixed 10 hour session using a permanent cookie that persists beyond the browser session. This means that even if you close all your browser windows and re-open it, you session is persisted and you are still logged in. The only way to logout is to explicitly do so.
While session persistence has some benefits, particularly around single sign-on and Office integration (you don't need to re-athenticate as you launch Word, Excel, PowerPoint, etc. from SharePoint), it has some drawbacks from a security perspective. If your Extranet is more about providing a secure web experience than Office integration, you probably don't want the persistent session. Thankfully there is an easy solution to the session persistence, in the form of a number of PowerShell commands we'll get to in a minute.
The other part of the problem is the 10 hour session. Again this is convenient, but not neccessarily best practice for all secure Extranets. You can shorten the session, but what we found was that it didn't slide. What this means is if you shorten it to 10 minutes, at 10 minutes your session will expire and you'll be force to re-authenticate, even if you were constantly using the site throughout those 10 minutes. What we wanted was for the session to expire after 10 minutes of inactivity. We found numerous articles and blogs talking about this, but they all involved some amount of code, and for the most part were focused on ADFS sessions, not FBA. We implemented a number of variations of code we found, including some great content in the CodePlex Claims Based Identity & Access Control Guide. While the guide gave us a much better understanding of claims, it still didn't solve our problem for us.
In our research, we came across a single post by Shawn Cicoria. It is titled SharePoint 2010 FBA and Sliding Sessions, and it notes that in the April CU, Microsoft provided support for sliding sessions. I haven't found the Microsoft details on this yet, but we did our testing on SP1 and June CU, and sure enough it worked for us. There was a small amount of PowerShell configuration needed, but no additional code.
For testing purposes we wanted to configure a 2 minute session, that was not persistent. To do this we did the following:
$sts = Get-SPSecurityTokenServiceConfig
$sts.UseSessionCookies = $true
$sts.FormsTokenLifetime = (New-Timespan –Minutes 2)
$sts.LogonTokenCacheExpirationWindow = (New-Timespan –Minutes 1)
$sts.Update()
iisreset
The first line gets the STS configuration object. The second line tells STS to use in memory session cookies, which means that when you close your browser your session is gone. The next two lines set the session timeout, and the last two commit the changes.
Shawn’s blog above gives a good set of scenarios that explains what the result of this is. There is a lot of confusion on the web over what the LogonTokenCacheExpirationWindow actually does, but here is my take on it. It is expensive to go back to the token service for every request and extend the session to keep it sliding. If you think about your home page, it is not just one request. Every element (image, CSS, JavaScript, etc.) is another turn to the server. Hitting the security service for every one of these would cause a significant performance hit on the server. I believe Microsoft’s intent (although they don’t explain it), is that during the LogonTokenCacheExpirationWindow, your session is not extended to improve performance. In the case of my timing this means if you hit the site again within a minute of your first hit, your session does not extend. Let’s say you hit the site 30 seconds after the first hit. If you wait 100 seconds from then and hit the site again, your session is expired, even though it is within two minutes of your last hit. Because your session didn’t get refreshed at 30 seconds, you still only have two minutes from the first hit before it expires. I’ve confirmed this behavior on our SP1 site.
You can balance having an exact session length with the performance hit on the server based on how small you make LogonTokenCacheExpirationWindow. Some blogs recommended setting it to 1 second “to get it to work”, but I don’t think they realized the performance implication of doing that, particularly on busy public sites. If you wanted a session timeout of 10-20 minutes, I would set the FormsTokenLifetime to that, and then set the LogonTokenCacheExpirationWindow somewhere between 2 and 5 minutes. Think of your actual session timeout as somewhere between the FormsTokenLifetime and the difference of FormsTokenLifetime – LogonTokenCacheExpirationWindow, depending on the user’s usage pattern.
Here's some scenarios you can use to test this behaviour out in your environment. It assumes you have at least April CU installed on your site, and that you have FBA configured and working.
Scenario 1
- Go to a page that requires authentication
- Log into the site
- Close all browser windows
- Re-open the browser and go back to the page that requires authentication
- You should be prompted to login again
Scenario 2
- Go to a page that requires authentication
- Log into the site
- Remain on the page with no activity for 2.5 minutes
- Refresh the page
- You should be prompted to login again
Scenario 3
- Go to a page that requires authentication
- Log into the site
- Remain on the page with no activity for 30 seconds
- Refresh the page
- You should still be logged in
- Remain on the page with no activity for an additional 100 seconds
- Refresh the page
- You should be prompted to login again
Note that this result is because the first refresh happened before the initial 1 minute cache expiration window, so the session was not renewed. Even though the next refresh was only 100 seconds after the previous, it was more than 2 minutes after the initial session, and so the session was expired
Scenario 4
- Go to a page that requires authentication
- Log into the site
- Remain on the page with no activity for 90 seconds
- Refresh the page
- You should still be logged in
- Repeat steps 3-5 as many times as desired. The session should continue to be extended for up to 10 hours (the session length on the original claim from the login)
- Remain on the page with no activity for 150 seconds
- Refresh the page
- You should be prompted to login again
For details and links on installing SharePoint SP1, please see my SharePoint 2010 SP1 Install post.