SharePoint: Users forced to re-authenticate unexpectedly

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

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

1. Output of Get-SPSecurityTokenServiceConfig from one of your SharePoint servers.
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 web-front-end (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 to browse the site before re-authentication is forced.  We can figure it out and know for sure with just a Fiddler trace of an initial user login, and the output of Get-SPSecurityTokenServiceConfig.

Get-SPSecurityTokenServiceConfig (with my comments highlighted)

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 Production farm.  I usually increase this to at least 5000 to start. The “proper” number depends on how many active users you have.
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-authenticate. You can get the SAML lifetime from a Fiddler trace if it covers the users 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 (or other SAML provider) server just before the POST to /_Trust/.  This is where the ADFS (or other SAML provider) server sends the SAML assertion to the client.
What we’re interested in here are the “Created” and “Expires” timestamps within the SAML assertion:

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 about user session management here.

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.

1. The SharePoint WFE server forcefully expires the FedAuth cookie by setting it to expire in 1970

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

Example:

This could happen for the following reasons:
• The default value for MaxLogonTokenCacheItems is 250, which is almost never enough.
This means that only 250 user tokens will be cached in the Distributed Cache. 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.
Now, in reality, it’s a little more complex than that. If you want to read about strong and weak reference cache, you can find that here, but suffice to say that to avoid unnecessary reauthentication, MaxLogonTokenCacheItems would be close to the number of active users you have in the farm during your FedAuth cookie lifetime.
For example, if your FedAuth cookie lifetime (which we discussed above) is 60 minutes, and you know you have roughly 4,500 active users during your peak 60 minute period on any given day, then I would set MaxLogonTokenCacheItems to 5,000.
While increasing this number will consume a little more memory, I’ve seen customers set it to 10,000 and higher with no issues.

• You’ve hit the LogonTokenCacheExpirationWindow.
Your FedAuth cookie is good for (SAML token lifetime -minus LogonTokenCacheExpirationWindow) as described above. When that time is up, you will be forced to reauthenticate.
This is expected. It’s just how it works. If that time period is too short, then you need to increase your SAML token lifetime.

• The app domain was unexpectedly unloaded or the app pool recycled, flushing the logon token from cache.
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 Distributed Cache, you could have this problem. Look for d-cache errors in the ULS logs.
• As a ‘best practice’, run the Distributed Cache tuning script that is appropriate for your version of SharePoint to optimize the Distributed Cache.

2. The client browser (IE, Chrome, Firefox, etc) drops the cookie.


Looking at a Fiddler trace, you see that it suddenly just no longer sends the FedAuth cookie along with the request to SharePoint.


• 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 the cookie after 15 minutes and be forced to re-authenticate, even if the cookie is good for 8 hours server-side.

The “SameSite” / “Secure” cookie issue.
Newer versions of Chrome and Edge browsers have a security feature where they will not send a cookie if it’s not properly stamped. You can read more about that here and here.

Add a Comment