SharePoint: Check Permissions and External Tokens – ADFS (SAML auth)

This post is the third part of a series on the "Check Permissions" function. It's focused on Trusted Provider authentication aka: SAML-claims.

The way "Check Permissions" works varies by authentication method. For Windows or FBA auth, see my other posts:

Windows-Claims Authentication:  https://blogs.technet.microsoft.com/spjr/2017/09/05/sharepoint-troubleshooting-check-permissions/ 
Forms-based Authentication (FBA):  https://blogs.technet.microsoft.com/spjr/2018/03/20/sharepoint-check-permissions-and-external-tokens-fba/

Notes:

  • I'll be talking about Active Directory Federation Service (ADFS), but the same concepts apply to other SAML auth providers like SiteMinder, Ping Federate, etc.
  • "Check Permissions" is not the only function that utilizes the External Token to determine user permissions.  Pretty much any non-interactive function in SharePoint that must determine a users permission will use the External Token.  Examples:
    • Alerts
    • Workflow
    • SQL Server Reporting Services (SSRS) report subscriptions.

First some background:

Please see the "Why should you care?" and "Background" sections of my Windows Auth post. That should provide some good background on External Tokens and interactive vs non-interactive refresh of the External Token, which should help explain why "Check Permissions" failures can be intermittent when the user gets their permission via group membership (role claim).

How is Trusted Provider / SAML / ADFS auth different?

With Trusted Provider auth, the "Check Permissions" functionality is completely dependent on your Custom Claims Provider (CCP). The CCP is responsible for looking up the user account (people picker), and augmenting their claims set (claims augmentation) by also looking up their group memberships / role claims. This claims augmentation is something that is implemented within the code of the CCP. That's important to keep in mind. It's quite possible that your CCP was not written to do augmentation, in which case there's nothing you can do in SharePoint to fix it. The CCP would have to be updated to support this functionality.

Prerequisites:

In order for this to work at all, you need to be passing group membership as a role claim, and you also need a Custom Claims Provider.

Check which claims you're passing:

Get-SPTrustedIdentityTokenIssuer |select claimtypeinformation -ExpandProperty claimtypeinformation

You can see I'm passing the Role claim:

Do I have a Custom Claims Provider?

I hope so. If not, your People Picker functionality on your Trusted Provider auth web applications is probably not great.

Get-SPTrustedIdentityTokenIssuer | select name, claimprovidername

My Custom Claims Provider is LDAPCP:

Troubleshooting:

This is going to depend on your Custom Claims Provider. As I mentioned earlier, the CCP is wholly responsible for providing this functionality. If it's not written to do this correctly (or maybe not at all), then you'll need to be in touch with the developers.

Troubleshooting Check Permissions with LDAPCP:

LDAPCP is an excellent custom claims provider. It covers most LDAP people picking scenarios out-of-box, and since it's an open-source project, you can tweak it to meet your needs.

I'm going to go into some depth for troubleshooting "Check Permissions" with LDAPCP because: 1.There are a lot of farms out there using LDAPCP or a customized version of it, and 2.The concepts can likely be applied to other custom claims providers as well.

1. Make sure you're adding your groups (role claims) to site permissions correctly.

The role claim you added to site permissions must match exactly the role claim within the users logon token. For example, I was recently testing this behavior and found that it wasn't working in my farm. Looking at site permissions, it looks like the correct group was added, but if I click on the group name, I can see the actual account name for the group:

Notice it's qualified by domain name "c:0-.t|adfs|joroar.local\group area"

However, I know that in ADFS, I'm passing unqualified group names, so it should be: "c:0-.t|adfs|group area"

If there's any question about the role claim format, I can grab a Fiddler trace of a user login and see which claims are being passed in the SAML assertion. Here I can confirm the group name should be unqualified:

So why did LDAPCP add the group to site permissions in domain-qualified format?

Looking at my claim mappings in LDAPCP, I see that for Role, there is a "Prefix to add to value returned" value set to "{fqdn}\"

Note: This is the default behavior for the version of LDAPCP that I tested with (V2017.06). It may not be the default for all versions.

After removing that, I can add the group back to site permissions and see that it's now added with the correct (unqualified) group name:

2. Enable Augmentation in LDAPCP

By default (at least in V2017.06), augmentation is not enabled in LDAPCP. In order for "Check Permissions" to work consistently, it must be enabled. The UI for the augmentation settings varies by LDAPCP version, but basically, you enable it, choose which claim is your role claim, and then use the check boxes to tell LDAPCP whether or not each of your LDAP connections are to Active Directory.

3. Upgrade .NET.

Since LDAPCP also uses the GetAuthorizationGroups method, the #1 cause from my Windows-auth blog post also applies here.

Solution: Install .NET Framework update 4.6.2. (or higher version)

Notes:

  • .NET Framework 4.6 is supported for SharePoint 2013 as long as you have SP1 installed.
  • You can check which version of .NET Framework you have installed using steps here.
  • It's important that you upgrade .NET on every SharePoint server in the farm.

4. Upgrade LDAPCP.

There have been several enhancements made to the augmentation functionality of LDAPCP across recent versions. At the time of this writing, the latest version is v11. I recommend installing / upgrading to the most recent version to get the most consistent experience.

5. Check other known-issues.

If you're using Active Directory as your back-end identity store, see Causes and Resolutions 1, 2, 4, 5, 8, and 9 from my Windows-auth blog post. They all apply here as well.