SharePoint: The Complete Guide to PortalSuperUserAccount and PortalSuperReaderAccount
What are the Super User and Super Reader accounts for?
This is explained pretty well on Docs here: https://docs.microsoft.com/en-us/SharePoint/administration/configure-object-cache-user-accounts
In general, they are used in the process of making SharePoint Publishing sites (any site using the publishing features) render quickly and efficiently.
Please keep in mind that these accounts are not actually required to be set on a web app. If you do not specify the accounts for a web app, SharePoint will just use the default system accounts. Publishing sites will continue to work. However, they won’t render quite as efficiently as noted in above Docs article. So it’s really a “recommended, but not required” situation. *I’ve never seen an “every user gets Access Denied” problem because the super user and super reader properties were not set (using the default accounts).* However, I’ve seen plenty where they were set to domain accounts, but done so improperly.
* A colleague informed me this can happen if NT Authority\Local Service does not have permission to the web app. See “Switch back to the out-of-box accounts” section below. The PowerShell script there automates this for you.
Rules for the accounts:
- They must be domain accounts, preferably from the same domain as your other SharePoint system accounts.
- You must use two separate accounts. One for Super User, one for Super Reader.
- They must be dedicated for only this purpose. Do not re-use other SharePoint service accounts for super user / reader, and by no means should you use an end-user account.
- Do not log into SharePoint sites using these accounts. Just set them and leave them alone. No one even needs to know the password.
- You can use the same two accounts for multiple web apps in the same farm, and across multiple farms if you like.
- People Picker must be able to resolve the accounts within the sites. If your people picker configuration or claim provider settings are such that the Super User / Reader accounts cannot be resolved, you will have problems. See the “Check your People Picker settings” section below for more info.
- It is recommended to use Windows authentication accounts. Your users may be primarily using Trusted Provider / SAML / OIDC authentication for the web application, but the Super User / Super Reader accounts should be set in Windows-claims format, for example: i:0#.w|contoso\superUser. While I’ve seen this work using accounts set in trusted provider format, for example: i:0e.t|adfs|superUser@contoso.com, it seems to be more solid using Windows auth. Since Window Authentication must be enabled on the web application for Search to work, this shouldn’t be an issue.
How to set them properly:
This is a three-step process.
- First you must give the accounts the proper permission within the web application User Policy.
- Then you must set the web application properties portalsuperuseraccount and portalsuperreaderaccount to the applicable account names.
- Then you must reset IIS or recycle the application pools for your web apps, on every server in the farm. Important! Whether you’re adding the property values to the web app or removing them, a recycle of the app pool (or IISReset) is required for the change to take effect.
To automate steps 1 and 2 above, you can use the following PowerShell script that I mostly borrowed / stole from this blog post.
I did tweak the script slightly so that all you need to specify is the $sOrigUser and $sOrigRead variables at the top.
It will set the super user and super reader values for every web application in the farm. It also automatically sets the required permissions in the web application user policy.
#SUPER USER ACCOUNT - Use a dedicated Account (NOT A SHAREPOINT ADMIN)
#Just specify the account in domain\userName format. The script will convert to claims notation if needed.
$sOrigUser = "contoso\SP_SuperUser"
#SUPER READER ACCOUNT - Use a dedicated Account (NOT A SHAREPOINT ADMIN)
#Just specify the account in domain\userName format. The script will convert to claims notation if needed.
$sOrigRead = "contoso\SP_SuperReader"
### Change nothing below this line ###
Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue
$apps = get-spwebapplication
foreach ($app in $apps) {
#DISPLAY THE URL IT IS BUSY WITH
$app.Url
if ($app.UseClaimsAuthentication -eq $true)
{
# IF CLAIMS THEN SET THE IDENTIFIER
$sUser = "i:0#.w|" + $sOrigUser
$sRead = "i:0#.w|" + $sOrigRead
}
else
{
# CLASSIC AUTH USED
$sUser = $sOrigUser
$sRead = $sOrigRead
}
# ADD THE SUPER USER - FULL CONTROL
$sUserName = $sOrigUser.substring($sOrigUser.LastIndexOf('\')+1)
$policy = $app.Policies.Add($sUser, $sUserName)
$policyRole = $app.PolicyRoles.GetSpecialRole([Microsoft.SharePoint.Administration.SPPolicyRoleType]::FullControl)
$policy.PolicyRoleBindings.Add($policyRole)
$app.Properties["portalsuperuseraccount"] = $sUser
$app.Update()
# ADD THE SUPER READER - READ ONLY
$sReadName = $sOrigRead.substring($sOrigRead.LastIndexOf('\')+1)
$policy = $app.Policies.Add($sRead, $sReadName)
$policyRole = $app.PolicyRoles.GetSpecialRole([Microsoft.SharePoint.Administration.SPPolicyRoleType]::FullRead)
$policy.PolicyRoleBindings.Add($policyRole)
$app.Properties["portalsuperreaderaccount"] = $sRead
$app.Update()
}
Write-host -ForegroundColor Green "Success."
Write-host -ForegroundColor Green "portalsuperuseraccount has been set to $sUser for all web apps"
Write-host -ForegroundColor Green "portalsuperreaderaccount has been set to $sRead for all web apps"
Write-host -ForegroundColor Red "Important! Please reset IIS on all web-front-ends to apply the change"
### - END SCRIPT ###
What happens if you do it wrong?
I’ve seen this messed up just about every which way:
- Forgetting to add the permission to the web app user policy, or giving the wrong permission to the wrong user.
- Adding the accounts in classic notation (domain\userName) instead of claims notation (i:0#.w|domain\userName) for a claims web app.
- Leading or trailing spaces in the account names.
- Probably some other stuff…
That’s the nice thing about the above PowerShell script. It automates this all for you so that all you need to do is enter the two account names in domain\userName format, and it takes care of the rest. It’s not quite fool-proof, but it’s better than manually doing it.
If you do mess this up somehow, you would see the following behavior:
Access Denied (“sorry, this site has not been shared with you”, or “sorry, you don’t have access to this page”)
You’ll see this on all of your publishing sites, for every user, including site collection administrators.
When I see an issue where suddenly every single account starts getting Access Denied, that’s a dead giveaway for a super user / super reader problem.
Notes:
- You may not see this behavior immediately, because like I said above, it takes an app pool recycle to make a super user / super reader change take effect.
- You will not see this behavior on out-of-box Team sites and the like, because by default, they don’t use SharePoint Publishing features.
Troubleshooting:
Check your ULS logs:
If the “everyone gets Access Denied” behavior doesn’t give it away, you would want to have a look at the SharePoint ULS logs.
You may find errors like this one from my SharePoint 2013 farm:
w3wp.exe (0x27A8) 0x425C SharePoint Foundation General ai1wu Medium System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)), StackTrace:
at Microsoft.SharePoint.SPWeb.GetList(String strUrl)
at Microsoft.SharePoint.Publishing.CacheManager..ctor(SPSite site)
at Microsoft.SharePoint.Publishing.CacheManager.GetManager(SPSite site, Boolean useContextSite, Boolean allowContextSiteOptimization, Boolean refreshIfNoContext)
at Microsoft.SharePoint.Publishing.Navigation.NavigationHelpers.TryParseUrlUntilWeb(HttpUrlBuilder sourceUrl, SPSite site, CachedArea& cachedArea, Int32& segmentIndexAfterWeb)
at Microsoft.SharePoint.Publishing.Navigation.TaxonomyNavigation.TryParseFriendlyUrlInternal(SPSite site, HttpUrlBuilder inputUrl, NavigationTerm& friendlyUrlTerm, String[]& catalogUrlSegments, CachedArea& cachedAreaForUrl)
at Microsoft.SharePoint.Publishing.PublishingHttpModule.PostAuthorizeRequestHandler(Object sender, EventArgs e)
at <truncated>
Here’s another sample error from my SharePoint 2016 farm. The error is a bit different, but we can see it’s still bubbling up from some Publishing Cache methods.
w3wp.exe (0x33AC) 0x05B0 Web Content Management Publishing Cache aytf3 Unexpected Exception when trying to fetch area in background thread “System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at Microsoft.SharePoint.SPGlobal.HandleUnauthorizedAccessException(UnauthorizedAccessException ex)
at Microsoft.SharePoint.Library.SPRequest.GetAclForCurrentWeb(String bstrWebUrl, Boolean fRequirePermissionCheck, Object& pvarRawAcl, UInt64& lAnonymousMask)
at Microsoft.SharePoint.SPWeb.GetReusableAcl(Boolean requirePermissionCheck, Boolean useCache)
at Microsoft.SharePoint.Publishing.AclCache.AddAclIfNecessary(Guid scopeId, SPSecurableObject o)
at Microsoft.SharePoint.Publishing.CachedArea..ctor(PublishingWeb area, String id, String parentId, CachedUserResource title, String url, CachedUserResource description, ICachedObjectFactory factory)
at Microsoft.SharePoint.Publishing.CachedArea.CreateCachedArea(PublishingWeb area, ICachedObjectFactory factory, String parentId)
at Microsoft.SharePoint.Publishing.CachedArea.CreateRefreshedVersion(List`1& newObjects)
at Microsoft.SharePoint.Publishing.CachedObjectFactory.ReSyncChangedCache()”.
The important part is highlighted. You need to look at the stack trace. If the Access Denied is coming from anything that says “Publishing Cache”, you should immediately suspect a super user / super reader problem.
Check the current configuration:
You can use this PowerShell to see which accounts are currently set for super user and super reader on each web application:
#Output super user / reader for all web apps:
add-pssnapin microsoft.sharepoint.powershell -ea silentlycontinue
$was = Get-SPWebApplication
foreach ($wa in $was)
{Write-host "Web App: " $wa.url
Write-host "Super User: " $wa.Properties["portalsuperuseraccount"]
Write-host "Super Reader: " $wa.Properties["portalsuperreaderaccount"]
Write-host " "}
Switch back to the out-of-box accounts:
You can use the below PowerShell to set the portalsuperuseraccount and portalsuperreaderaccount properties back to using the default accounts.
This is typically the first thing I’ll do when I suspect a super user / super reader problem.
#This is how you properly remove the super user and super reader properties and set them back to default
#The only change you need to make is to enter the web app URL
$url = "https://<TheWebAppURL>"
### Change nothing below this line ###
add-pssnapin microsoft.sharepoint.powershell -ea silentlycontinue
$wa = Get-SPWebApplication -Identity $url
#Remove the values for the properties, which sets them back to using the default accounts:
$wa.Properties.Remove("portalsuperuseraccount")
$wa.Properties.Remove("portalsuperreaderaccount")
#Make sure NT Authority\Local Service has permission
$account = "NT Authority\Local Service"
$roleName = "FullRead"
$policy = $wa.Policies.Add($account, $account)
$role = $wa.PolicyRoles.GetSpecialRole($roleName)
$policy.PolicyRoleBindings.Add($role)
$wa.Update()
Write-host -ForegroundColor Red "Important! Please reset IIS on all web-front-ends to apply the change"
Again, you’ll need to reset IIS or recycle the app pools on each of the web-front-end (WFE) servers in order for the change to take effect.
If your sites are back up after setting super user and super reader back to the default accounts, then you need to take a look at how you configured the accounts.
Check your People Picker settings:
This may not seem intuitive, but in order for the publishing controls to work, the super user and super reader accounts must be resolvable in Active Directory.
If you have your web application people picker settings set in such a way that the super user and / or super reader account cannot be resolved by People Picker, you will have problems.
You can check your People Picker settings with this PowerShell:
$wa = Get-SPWebApplication http://<TheWebApplication>
$wa.PeoplePickerSettings
The most common culprits are improper configuration of these People Picker properties:
- SearchActiveDirectoryDomains
- ActiveDirectoryCustomQuery
- ActiveDirectoryCustomFilter
You should also check the output of Get-SPClaimProvider and make sure the “Active Directory” claim provider (assuming you’re using Windows authentication Super accounts) has both IsEnabled and IsVisible set to True.