Users forced to re-authenticate unexpectedly

This post covers the scenario where users log in via a trusted provider / SAML-claims  (like ADFS, Ping, Site Minder, etc) and intermittently, they are redirected to the login page to re-authenticate.

There are a few pieces of information you need for a scenario like this (beyond the regular scoping):

1. Output of Get-SPSecurityTokenServiceConfig
2. A Fiddler trace showing the initial SAML-claims login, and where the user is forced to re-authenticate.
3. SharePoint ULS logs that cover the time period for #2, from the WFE that was accessed.
4. Output of Get-SPTrustedIdentityTokenIssuer can be helpful too.
5. If using ADFS, you can get the token lifetime from the ADFS server like this: (get-ADFSRelyingPartyTrust "SharePoint 2013").TokenLifeTime
-Where "SharePoint 2013" is the name of your relying party trust.
-A value of zero means it's using the default value, which is 8 hours.
-However, this is not required.  We can figure it out from the Fiddler trace noted in #2 above.

We need to know exactly how long the client should have before re-authentication is forced.  We can figure it out and know for sure with just a Fiddler trace and the output of Get-SPSecurityTokenServiceConfig.

 

Get-SPSecurityTokenServiceConfig

SecurityTokenServicePublicUrlSuffix         : /_vti_bin/spsecuritytokenserviceactive.svc
SecurityTokenServiceMetadataPublicUrlSuffix : /_vti_bin/spsecuritytokenserviceactive.svc/mex
LocalLoginProvider                          : SPLocalLoginProvider Name=SharePoint
TrustedLoginProviderNames                   : {ADFS 2013}
TrustedLoginProviders                       : {ADFS 2013}
TrustedAccessProviders                      : {}
TrustedSecurityTokenServices                : {Exchange}
AuthenticationPipelineClaimMappingRules     : {WindowsMappingRule}
AllowMetadataOverHttp                       : True
UseSessionCookies                           : False <-- False = FedAuth cookie is stored on disk client-side (persistent cookie).  True = FedAuth cookie is stored in browser memory (session cookie).
WindowsTokenLifetime                        : 00:10:00
FormsTokenLifetime                          : 10:00:00
CookieLifetime                              : 5.00:00:00  <-- This is how long the FedAuth cookie is good on the client side.  Default is 5 days.  However, this is not necessarily how long it’s good on the server-side.
ServiceTokenLifetime                        : 10:00:00
MaxLogonTokenCacheItems                     : 250 <-- Max number of logon tokens that are cached server side.  Default is 250, which is almost never enough for a prod farm.  I usually increase this to 5000
MaxLogonTokenOptimisticCacheItems           : 100000
LogonTokenCacheExpirationWindow             : 00:10:00 <--The SAML assertion lifetime minus this value is how long we have before the server kills the FedAuth cookie and forces you to re-auth. You can get the SAML lifetime from a Fiddler trace if it covers the SAML login.
MaxServiceTokenCacheItems                   : 250
MaxServiceTokenOptimisticCacheItems         : 100000
ServiceTokenCacheExpirationWindow           : 00:10:00
ApplicationTokenLifetime                    : 1.12:00:00
AuthenticatorTokenLifetime                  : 1.12:00:00
MinApplicationTokenCacheItems               : 250
MaxApplicationTokenCacheItems               : 100000
ApplicationTokenCacheExpirationWindow       : 00:10:00
LoopbackTokenLifetime                       : 10:00:00
AllowOAuthOverHttp                          : True
<truncated…>

 

Fiddler Trace

This should be taken while the client is initially logging in so we can see the SAML assertion.
Look for the communication with the ADFS server just before the POST to /_Trust/.  This is where the ADFS server sends the SAML assertion to the client.
What we're interested in here is the Created and Expires timestamps on the SAML assertion:

Note: to see the SAML assertion in the nice formatted output on the "Federation" tab in Fiddler, you need the Thinktecture Federation Inspector dll add-on as described here.

The timestamps are in UTC time, but the important part is their difference.  In this case, I can see that my SAML assertion is good for 1 hour.
SAML assertion: 60 minutes
- (minus)
LogonTokenCacheExpirationWindow: 10 minutes
--------------------------------------------------------------------
In this case, the FedAuth cookie is good on the server-side for 50 minutes.

More Info on this:
https://blog.robgarrett.com/2013/05/06/sharepoint-authentication-and-session-management/  https://blogs.technet.com/b/speschka/archive/2010/08/09/setting-the-login-token-expiration-correctly-for-sharepoint-2010-saml-claims-users.aspx

 

There are a few reasons why the FedAuth cookie would unexpectedly expire, forcing users to re-authenticate.

There are usually two distinct scenarios:
1: The SharePoint server forcefully expires the FedAuth cookie
2: The client browser loses the FedAuth cookie

You can determine which one you're hitting with a Fiddler trace, paired with ULS logs.

 

-- You would see this in the server response in Fiddler:
Set-Cookie: FedAuth=; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=/

This could happen for the following reasons:

• The default value for MaxLogonTokenCacheItems is 250, which is typically not enough.
o This means that only 250 user tokens will be cached per web-front-end.  When user 251 logs into the site, the login token for user 1 gets pushed out of the cache.  When user 1 tries to interact with the site again, they are forced to re-authenticate.

• You've hit the LogonTokenCacheExpirationWindow.  Your FedAuth cookie is good for (SAML token lifetime -minus LogonTokenCacheExpirationWindow)

• The app domain was unexpectedly unloaded or the app pool recycled.  You could see something like this in the ULS logs:
07/01/2015 18:36:53.61 w3wp.exe (0x26C0) 0x0418 Web Content Management Publishing 8fjh High AppDomainUnloadListener.Stop(False) called. ShutdownReason=MaxRecompilationsReached, this=64949060

07/01/2015 18:37:19.20    w3wp.exe (0x26C0)    0x26B0    SharePoint Foundation    General    avey    High    The application domain /LM/W3SVC/936297162/ROOT-4-130802673074532241 is unloading and going to be recycled.

07/01/2015 18:37:19.20 w3wp.exe (0x26C0) 0x26B0 SharePoint Foundation General avez Medium Shutdown Reason: Recompilation limit of 15 reached  HostingEnvironment initiated shutdown  HostingEnvironment caused shutdown

Note: The users authentication token is cached within that app domain (in memory in the W3WP.exe process).  When it recycles, that memory space is cleaned out and the cached authentication tokens are lost.  When the users browser sends the FedAuth cookie again, the server cannot find a match in the cache and must force the user to re-authenticate.  You'd see the same behavior if you reset IIS or recycled the app pool in the middle of a users session.

• Problems with the server caching the logon token:
SharePoint 2010
• The logon tokens are cached in W3WP.exe on each WFE.
• The load balancer is sending you to a different WFE that does not have the token cached -- (load balancer sticky session / affinity / persistence issue)
• A users logon token is cached in memory on a given Web-Front-End (WFE) server.  If you first authenticate to WFE1, and then a few minutes the load balancer sends you to WFE2, your logon token will not be cached on WFE2.  In this situation, SharePoint forces an expiration of the FedAuth cookie and forces re-authentication.

SharePoint 2013:

  • The logon tokens are stored in the Distributed Cache.
  • If there is any problem fetching the token from the D-cache, you could have this problem.  Look for errors in the ULS logs.
  • As a 'best practice', run this PowerShell script to optimize your Distributed Cache.

 

• The client browser drops the cookie.  All of a sudden it just no longer sends the FedAuth cookie with the request.
o Internet Explorer has a Max number of cookies per-domain (per host) of 50.  https://support.microsoft.com/en-us/help/941495/internet-explorer-increases-the-per-domain-cookie-limit-from-20-to-50

• Could be that the SharePoint site is setting too many cookies for each page browse, due to customizations on the site.

• Cookielifetime setting in SharePoint 2013 (Get-SPSecurityTokenServiceConfig).  By default, this is set to 5 days, which means the client will continue trying to use it for 5 days, or until the server forcefully expires it.  However, this could be set to a much lower value.  If it's set to 15 minutes, the client will drop it after 15 minutes and be forced to re-authenticate, even if the cookie is good for 8 hours on the server side.