SharePoint: Cross-forest group memberships not reflected by Profile Import

Consider the following scenario:

  • You have an Active Directory Forest trust between your local forest and a remote forest.
  • You create a “domain local” type security group in Active Directory and add users from both the local forest and the remote trusted forest as members.
  • You configure SharePoint Profile Synchronization to use Active Directory Import and import users and groups from both forests.
  • You create an Audience within the User Profile Service Application (UPA) using the “member of” option and choose your domain local group.
  • You compile the audience and find that the number of members it shows is less than you expect.
  • You click “View membership” on the audience and find that the compiled audience shows only members from your local forest.

For example, my AD group called “Cross-Forest-Group” contains 2 members from my local forest, and 2 members from my trusted forest, but the audience I built based on membership of that group only shows the 2 users from my local forest.

! Important !

My example above covers a scenario involving Audiences, but this also impacts claims augmentation and OAuth scenarios.

For example, let’s say you give permission to a list or a site using an Active Directory security group with cross-forest membership. You can do that, it works. Those users from the trusted forest will be able to access the site. However, if you run a SharePoint 2013-style workflow against that list, it looks up the user and their group memberships within the User Profile Service Application (UPA). Since the UPA does not show the trusted forest users as members of the group, the claims augmentation function does not think the user belongs to that group and the Workflow fails with 401 – Unauthorized.

More information about the little-known workflow-group-UPA connection:

http://www.sharepoint4developers.net/en-nz/post/sp2013-workflows-suspended-state.aspx

http://prairiedeveloper.com/2016/06/sharepoint-2013-workflow-failing-immediately-starting/

Common OAuth scenarios that could be impacted:

  • Workflow Manager (SharePoint 2013 workflows)
  • Office Web Apps (OWA) / Office Online Server (OOS)
  • High Trust or Low Trust Provider-Hosted Apps
  • Hybrid SharePoint 2013 / SharePoint Online scenarios
  • SharePoint Integration with Exchange

Why does this happen?

It’s a limitation of the way that users and groups are imported into the User Profile Service Application and group membership is calculated.

If you look at the group in Active Directory, you’ll notice that the members from your trusted forest are not actually user objects, instead they are foreign security principals.



How do we work around this?

The only solution is to use two separate groups in your audiences and site permissions.

Use a group from the local domain to include your local forest users and use a group from the trusted domain to include your trusted forest users.

You can add multiple “member of” rules to a single audience to include users from both groups. Just be sure to use the “Satisfy any of the rules” operator.

Now my audience shows members from both Forests:



Group / Audience Troubleshooting tips:

It can be a bit difficult to tell which groups the User Profile Service Application (UPA) thinks a certain user is a member of, or which users are members of a certain group.

You can use these SQL queries against the Profile database to get that info.

Note: These queries are written for SharePoint 2016 and above. For SharePoint 2013, you would need to drop the “upa.” part from in front of the table names: userprofile_full, usermemberships, and membergroup. You only need to supply your own group or user name.

-- Return group members (all members of a specific group)
select mg.displayname as GroupName, mg.Id as GroupID, mg.SourceReference as GroupDN, upf.ntname as UserName, upf.PreferredName, upf.RecordID as UserID from upa.userprofile_full upf (nolock)
join upa.usermemberships um (nolock) on upf.recordid = um.recordid
join upa.membergroup mg  (nolock) on um.membergroupid = mg.id
where mg.displayname like '%your Group here%'
order by mg.displayname, upf.ntname
-- Return user memberships (all groups a certain user belongs to)
select upf.ntname as UserName, upf.PreferredName, upf.RecordID as UserID, mg.displayname as GroupName, mg.Id as GroupID, mg.SourceReference as GroupDN from upa.userprofile_full upf (nolock)
join upa.usermemberships um (nolock) on upf.recordid = um.recordid
join upa.membergroup mg (nolock) on um.membergroupid = mg.id
where upf.ntname like '%your User Name here%'
order by upf.ntname,  mg.displayname

If you find that group membership within the UPA does not properly reflect membership within Active Directory, see this related issue I wrote about a while back:

Membership calculation is done as part of the Profile Import job. Both groups and their member users must be imported for the membership relationships to be built properly.

You’ll want to make sure that the AD containers / OUs that contain both the users and the groups are selected within your import connection, and that the connection filter does not exclude them.

Aside from that, you can review logs to see what’s going wrong.

Set Sharepoint logging to Verbose, run a Full Synchronization, and review the logs that cover the duration of the AD Import timer job.

You can filter the log by the “User Profiles” category and look for runs of the “UserProfileADImportJob” timer job.