Alternative title: “the mystery of the SharePoint security token caches”.
Something that comes up now & then is why SharePoint seems to say a user has no permissions for something when said users clearly do have access when they try (or the opposite too). Checking permissions looks something like this; you go-to the thing you want to check access for & enter a username to check effective access:
This is the usual way of verifying actual permissions for something for someone – it’s quite useful in fact, given the variety of ways users can inherit permissions making the calculation quite complicated.
The problem is though that with AD group-based permissions in particular, the tool can often get confused on what permissions there really are, and even more so when SharePoint is running in a separate domain from the users domain.
Why? Read on to find out. This subject is all about authorisation and not authentication - if you don’t know the difference then none of this will make any sense.
TL;DR: If “check permissions” isn’t showing the right results it’s probably because they haven’t logged into the site in a while and the external security token is out of date. Wait 1 hour; try again.
User Security Tokens for Authorisation
Something SharePoint does for authorisation is store security tokens for a user, so as to not need to query $securityProvider each and every time it needs to authorise something for a user. That thing might be page-access (the most common type of authorisation), or also maybe some kind of background-check for when a workflow runs under the context of a user updating items in a list – is the user authorised to do so? Either way security tokens is the SharePoint way of mapping out what claims the user has so we can know if they should or should-not be able to do something, somewhere in SharePoint.
But wait; there’s two types of user security tokens. First, there’s just standard “security tokens” which are used for accessing on-demand resources (accessing sites via a web-browser for example) but also “external tokens”, which are just copies of the same security token given on logon but persisted to SQL Server so can be used for less urgent background checks (like in workflows for example). Normally we call both types of tokens just “security tokens” but as you’ll see, not all tokens are equal.
The difference between these two types of tokens are key to why the permission check may say one thing, but actual authorisation may give a different result. This is a bit complex so bear with me here.
Generating Security Tokens – When it Happens
In short, security tokens are generated each time the user logs-in to SharePoint, otherwise known as an “interactive login”. Pretty simple.
When do external tokens get generated then? That’s more complicated; it’s when either an “interactive” or “non-interactive” login is done for the user and the token cache has expired. Let me explain…
What’s the difference between an interactive and non-interactive login? As mentioned; interactive logins are the user in question actually doing something themselves; accessing the site in a browser for example. What actually happens is that once the user is authenticated, SharePoint receives all the membership information (groups, etc) from the identity provider in question and from here SharePoint generates a new security token for the user. Non-interactive logins are done when SharePoint needs to authorise the user for something but the user isn’t thereinteractively as part of the process (hence the term); background SharePoint tasks, basically.
For every interactive login the SharePoint security token is generated, stored in memory/cache but also, if necessary is saved in the “external token” field in the content database too in case any background tasks or “non-interactive logins” need the info for the user (but crucially, only if the external token needs updating). Now we have both types of tokens and background tasks like checking permissions for example will use this information.
Security tokens are generated with every interactive logon. External tokens are refreshed maximum once an hour for interactive logons, but are valid for 24 hours for non-interactive logons.
In example: while the user keeps browsing constantly (or once an hour at least), external tokens are updated every hour with every interactive login done. If the user stops browsing, after an hour a new external token will be generated for any new interactive login, but if there’s no interactive login the external token is still good for 24 hours for any background task authorisation specifically. After 24 hours, any kind of authorisation or logon for that user will need to rebuild a new external token no matter what.
Now it should become clearer how we can end up with conflicting permission reports – external tokens are cached for up-to 24 hours by default to overloading Active Directory (or whatever other identity provider is in use) so sometimes don’t reflect any recent changes in user memberships.
Security Token Caching Problem
In case you haven’t already guessed, “check security” is based on the external security token. Knowing that it can be 24 hours before the external security is refreshed immediately suggests one obvious cause for any permission mismatches. If a user hasn’t physically logged into SharePoint within 24 hours then we won’t see any changes in actual security in AD until up-to 24 hours later.
Solutions:
- Reduce the validation period that external tokens are valid for (see below).
- Give permissions based on SharePoint groups.
The second option is preferable as there’s no time-delay in change –> authorisation effect.
Reducing External Token Timeout
If 24 hours for an external refresh is too long for you (it normally isn’t), you can change this default value with either:
stsadm -o setproperty -pn token-timeout -pv 5
…or…
$cs = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$cs.TokenTimeout = New-TimeSpan -Minutes 2
$cs.Update()
Important: don’t make the value less than 2 minutes – less than that & bad things happen. This also applies for all web-applications; you can’t just do it for one.
Problems Refreshing Security Tokens with Multiple Domains
Another problem can come when the external token needs refreshing without an interactive login. If we “check permissions” for user X say and user X’s external token needs refreshing, SharePoint does an “non-interactive login” for user X to repopulate the external token & read again group-membership info to get access info. This normally works but often the SharePoint service-account doesn’t have to the users’ domain as it’s a one-way trust so gets back 0 groups from the operation; it’ll populate the external token accordingly anyway, thus the permissions check gives back “no access”.
That doesn’t matter though because doing an “interactive login” will give the real membership info for the token every time because it’s authorised directly from a users DC which does give full group membership, and it all works fine. Access isn’t affected because we don’t authorise page-visits based on the external token; just background permission checks (this, alerts, workflows etc).
Wrap-Up
So this should explain some of the darker mysteries about how SharePoint does it’s permission-granting & authorisation logic. Credit to my good friend & colleague Jesus Fernandez Saez for contributing on this subject!
Cheers,
// Sam Betts