Sharepoint - SharePoint 2013 ADFS login local token cache always expired
The solution: the clock was wrong.
After a great deal of debugging using what @Nikhil provided as a guide, I eventually found the root cause of my expiring token issue: the clock on the SharePoint server was exactly one hour ahead of the clock on the ADFS server. The time zones were set wrong as well, so visually the clocks looked right, but the UTC time was one hour off.
Consider this scenario:
- ADFS issues a token (default lifetime of 60 minutes) to SharePoint at 10:00 AM Mountain Time and stamps the token with that time.
- SharePoint receives token and checks its clock, which reads 10:00 AM Pacific Time (aka 11:00 AM Mountain Time). Compares that time to the time that the token was issued and sees that the token has entered the expiration window (the token is only valid for 60 minutes and when there are less than 10 minutes left in the lifetime SharePoint considers it expired). SharePoint rejects the token and asks for a new one, and we enter the cycle that eventually leads to a thrown exception from ADFS because of too many requests within a few seconds.
While working through this I used a couple of simple PowerShell commands that gave me a lot of information. And I should specify that in order to solve this issue I did not have to make any changes to any configuration in either SharePoint or ADFS. I only had to change my clock. And hang my head in shame.
Useful commands:
Get-SPSecurityTokenServiceConfig
(SharePoint 2013 Application Server): Gives you all of the details about the Security Token Service on your SharePoint farm. Including things such as token cache expiration windows (LogonTokenCacheExpirationWindow
). Any changes you make to the properties can be saved by using the .Update()
method.
Get-ADFSRelyingPartyTrust -Name "My RP Name"
(ADFS Server): Provides details about the Relying Party Trust that you created for your SharePoint server. Key information here is the TokenLifetime
property. Saving changes to this isn't as easy; instead us Set-ADFSRelyingPartyTrust -TargetName "My RP Name" -[PropertyName] [new value]
I learned two important lessons in this process:
- The token lifetime is determined by the Relying Party Trust in ADFS, and is stamped with the local time of that server before being sent to SharePoint. SharePoint is in charge of determining when it feels that the token has expired (based on the
LogonTokenCacheExpirationWindow
property). Both of these properties can be changed but unless you have a very specific scenario, there is likely no need. Default values work fine. - Step one with any kind of security troubleshooting is to check the bloody clock!
Helpful resources:
http://msdn.microsoft.com/en-us/library/hh446526.aspx
http://msdn.microsoft.com/en-us/library/hh147183(v=office.14).aspx
http://iamprogrammerdotnet.blogspot.com/2012/07/same-client-browser-session-has-made-6.html
LogonTokenCacheExpirationWindow :Check the event viewer of ADFS and check if there is any exception like mentioned below.
Microsoft.IdentityServer.Web.InvalidRequestException: MSIS7042: The same client browser session has made '6' requests in the last '11' seconds. Contact your administrator for details.
at Microsoft.IdentityServer.Web.FederationPassiveAuthentication.UpdateLoopDetectionCookie()
at Microsoft.IdentityServer.Web.FederationPassiveAuthentication.SendSignInResponse(MSISSignInResponse response)
That’s because the default LogonTokenCacheExpirationWindow for the SharePoint STS is 10 minutes. The relying party by default it sets 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. Therefore it goes back to ADFS to authenticate again. And so it goes , back and forth. So I needed to change the LogonTokenCacheExpirationWindow to be less than the SAML TokenLifetime.
The solution is PowerShell Script:
sts = Get-SPSecurityTokenServiceConfig
$sts.LogonTokenCacheExpirationWindow = (New-TimeSpan –minutes 1)
$sts.Update()
iisreset
OR There might be issue with the Sliding session , http://msdn.microsoft.com/en-us/library/hh446526.aspx
OR
Check the web.config if everything is configured correctly .See if the SSL configuration is configured correctly . Check if the Cookies ,session ,cache are cleared properly , these are the typical scenarios where this issues occurs. Most important check if the powershell script ran is successful to establish trust between AD and SP.