Pregunta

I'm facing problems when calling SPWeb.DoesUserHavePermissions() for outdated user accounts.

Within a timer job I want to check if all users in SPSite.RootWeb.SiteUsers still have access to that site:

foreach (SPUser user in site.RootWeb.SiteUsers)
{
  try
  {
    if (site.RootWeb.DoesUserHavePermissions(user.LoginName, SPBasePermissions.ViewPages))
    {
        // do something
    }
    ...

This timer job runs in a SharePoint 2013 environment. The Web Application uses Claims Based Authentication.

Calling DoesUserHavePermissions() for an outdated SPUser object takes ~30+ secconds and throws an SystemException.

An example for a user logon that cannot be resolved because its domain does not exist anymore:

Exception:System.SystemException: The trust relationship between the primary domain and the trusted domain failed.
   at System.Security.Principal.NTAccount.TranslateToSids(IdentityReferenceCollection sourceAccounts, Boolean& someFailed)
   at System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess)
   at System.Security.Principal.NTAccount.Translate(Type targetType)
   at Microsoft.SharePoint.Administration.Claims.SPClaimProviderManager.GetProviderUserKeyClaim(IClaimsIdentity claimsIdentity, SPClaim loginClaim)
   at Microsoft.SharePoint.Administration.Claims.SPClaimProviderManager.GetProviderUserKey(IClaimsIdentity claimsIdentity, String encodedIdentityClaimSuffix)
   at Microsoft.SharePoint.Administration.Claims.SPClaimProviderManager.GetProviderUserKey(String encodedIdentityClaimSuffix)
   at Microsoft.SharePoint.Utilities.SPUtility.GetFullUserKeyFromFullName(String fullName)
   at Microsoft.SharePoint.SPGlobal.CreateSPRequestAndSetIdentity(SPSite site, String name, Boolean bNotGlobalAdminCode, String strUrl, Boolean bNotAddToContext, Byte[] UserToken, SPAppPrincipalToken appPrincipalToken, String userName, Boolean bIgnoreTokenTimeout, Boolean bAsAnonymous)
   at Microsoft.SharePoint.SPWeb.InitializeSPRequest()
   at Microsoft.SharePoint.SPWeb.EnsureSPRequest()
   at Microsoft.SharePoint.SPSite.GetEffectiveRightsForAcl(SPReusableAcl acl)
   at Microsoft.SharePoint.Utilities.SPUtility.GetPermissionsCore(SPUserToken token, SPSecurableObject securableObject, Boolean getAssignments, Boolean useCache)
   at Microsoft.SharePoint.Utilities.SPUtility.GetPermissions(String login, SPWeb web, SPSecurableObject securableObject, Boolean useCache)
   at Microsoft.SharePoint.SPWeb.DoesUserHavePermissions(String login, SPBasePermissions permissionMask)

Having a lot of these outdated user accounts in Web.SiteUsers really slows down my timer job.

Any idea how to speed up this piece of code? Or is there a (significant faster) alternative for DoesUserHavePermissions() that can deal with outdated users?

¿Fue útil?

Solución

I guess, since the expired users data stays in the site DB, 'SiteUsers'/'AllUsers' will return even the expired domain users that were once added to the site. Here is a possible solution I can think of.

If you have user profiles synchronized from the active directory into your user profile service application and the synchronization periodically updates the profiles, then the expired domain users might have been deleted from the user profiles.

You can try to get the UserProfile in the code as shown here. If the user profile is not returned, it means that the user does not exist and you can skip your code block on this condition. This may save your delay. But you need to use this carefully for your situation.

Licenciado bajo: CC-BY-SA con atribución
scroll top