Set up OIDC in SharePoint Server with AD FS

SharePoint Server Subscription Edition was released with support for OIDC based authentication. This tutorial will demonstrate an example implementation with AD FS that allows for using your own identity provider while at the same time, prevents the use of classic Windows authentication for better security. It also assumes that you are using Active Directory as attribute store for claims. As claim provider we will be using the open source solution LDAPCP.

What is OIDC?

OpenID Connect (OIDC) is an identity layer built on top of the OAuth 2.0 framework. It allows third-party applications to verify the identity of the end-user and to obtain basic user profile information.

Auth0

What is AD FS?

Active Directory Federation Services (AD FS), a software component developed by Microsoft, can run on Windows Server operating systems to provide users with single sign-on access to systems and applications located across organizational boundaries.

Wikipedia

Prerequisites

  • An up-to-date SharePoint Subscription Edition Farm
  • All required service applications, most notably the User Profile Service application
  • Web application(s):
    • Windows Authentication enabled for the default alternate access mapping. This is a requirement for the search crawler to work correctly. To prevent outside access you can use a firewall or reverse proxy. Example: http://sharepoint.local
    • Extended alternate access mapping with HTTPS that will be used with OIDC. This is what your users will be using from for example, the internet zone. Example: https://sharepoint.contoso.com

Configure AD FS

Perform the following steps to create the OIDC application AD FS that will be used as Trusted Identity Provider in SharePoint.

  1. Open AD FS management
  2. Create an application group from the “Web browser accessing a web application” template
  3. Note down the Client Identifier as this will be used later when configuring SharePoint
  4. Add the following claim issuance transformation rules from the Send LDAP Attributes as Claims template:
    • User-Principal-Name = UPN
    • Token-Groups as SIDs = Group SID
    • Token-Groups unqualified names = Role
  5. Add the following rule from the Send Claims Using a Custom Rule template:
    c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"] => issue(Type = "nbf", Value = "0");

Configure Trusted Identity Provider in SharePoint

What is a Trusted Identity Provider?

A trusted identity provider in SharePoint is used for authenticating users. We previously configued AD FS and will now configure SharePoint to trust identity tokens issued by AD FS.

  1. Open SharePoint Management Shell as administrator
  2. Generate a certificate for cookie signing:
    $cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -Provider 'Microsoft Enhanced RSA and AES Cryptographic Provider' -Subject "CN=SharePoint Cookie Cert" -NotAfter (Get-Date).AddYears(30)

    $f = Get-SPFarm
    $f.Farm.Properties['SP-NonceCookieCertificateThumbprint']=$cert.Thumbprint
    $f.Farm.Properties['SP-NonceCookieHMACSecretKey']='seed'
    $f.Farm.Update()
  3. In a multi-server farm, export the generated certificate and import it to the machine store on all other servers in the farm
  4. On each server in the farm, grant permissions to the cookie signing certificate to the application pool account:
    $ApplicationPoolAccount = "CONTOSO\SP_POOL"

    $cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Subject -eq "CN=SharePoint Cookie Cert" }
    $rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
    $fileName = $rsaCert.key.UniqueName
    $path = "$env:ALLUSERSPROFILE\Microsoft\Crypto\RSA\MachineKeys\$fileName"
    $permissions = Get-Acl -Path $path
    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($ApplicationPoolAccount, 'Read', 'None', 'None', 'Allow')
    $permissions.AddAccessRule($accessRule)
    Set-Acl -Path $path -AclObject $permissions
  5. Create the Trusted Identity Provider:
    $Name = "adfs" # Identifier of trust and claim provider, prefix on login names
    $AdfsUrl = "https://adfs.contoso.com"
    $AdfsClientApplicationIdentifier = "ADFS_CLIENT_IDENTIFIER" # See Configure AD FS

    $upn = New-SPClaimTypeMapping "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" -IncomingClaimTypeDisplayName "UPN" -SameAsIncoming
    $role = New-SPClaimTypeMapping "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" -IncomingClaimTypeDisplayName "roles" -SameAsIncoming

    $metadataendpointurl = "$AdfsUrl/adfs/.well-known/openid-configuration"

    $trust = New-SPTrustedIdentityTokenIssuer -Name $Name -Description $Name -ClaimsMappings $upn, $role -IdentifierClaim $upn.InputClaimType -DefaultClientIdentifier $AdfsClientApplicationIdentifier -MetadataEndPoint $metadataendpointurl

    $trust.UseWReplyParameter = $true
    $trust.GroupClaimType = $role.InputClaimType
    $trust.Update()

Prevent sharing with Windows accounts

To securely prevent Windows accounts accessing SharePoint you must configure a LDAP filter. Even if the user interface will only allow permission assignment to your selected identity providers, you can still assign permissions to any identity programatically. For SharePoint to work properly, the service accounts must still be resolvable however. You can configure the filter using SharePoint Management Shell.

$WebApplication = "Portal Home", "MySite Host"
$LdapFilter = "(&(objectCategory=person)(objectClass=user)(|(sAMAccountName=sp_cacheread)(sAMAccountName=sp_cacheuser)(sAmAccountName=sp_crawl)(sAmAccountname=sp_farm)(sAmAccountname=sp_Install)(sAmAccountname=sp_pool)(sAmAccountname=sp_services)))"

$WebApplication | Foreach-Object {
    Set-SPPeoplePickerConfig -WebApplication $_ -ActiveDirectoryCustomFilter $LdapFilter
}

LDAPCP as Claims Provider

With the Trusted Identity Provider we can authenticate users, but it is not fully usable by itself. It cannot handle permissions set on a user attribute, such as a security group membership. SharePoint also does not yet know how to search our identity store, like when using a people picker. This is where claims providers comes in.

In SharePoint Subscription Edition a claim provider called User Profile Application Claims Provider is included out of the box. However, it does not yet support claim augmentation, meaning that a identity token cannot be augumented with group memberships. This makes it unsuitable for most production scenarios.

There is no online documentation explaining this, but it was confirmed to us by Microsoft escalation engineers.

In this example we will be using LDAPCP, a open source claims provider. As the name implies it uses the LDAP protocol to search our identity store, usually this is Active Directory.

  1. Follow the installtion instructions for LDAPCP
  2. Open SharePoint Central Administration and go to Security > LDAPCP Configuration > Global configuration
  3. Configure the LDAP connection. In this example we are using the user profile synchronization service account, that should have the required access to Active Directory.
  4. Configure augmentation with the role claim. See the claims mappings in the trusted identity provider we created eariler.
  5. Configure how user names are displayed.
  6. Save by clicking OK at the bottom of the page.
  7. Open SharePoint Central Administration and go to Security > LDAPCP Configuration > Claim types configuration. Configure the mappings as in the image blow. Notice that we have removed the prefix on groups, since we have mapped role to unqualified group names in AD FS.

User Profile Synchronization

User Profile Service Application has many purposes and must be correctly configured according to the Trusted Identity Provider. For example, if a OU is missing or identity claim is mapped to the wrong property, OAuth authentication will not work, such as add-ins or Office Online Server.

When configuring the synchornization connection, ensure that:

  1. You are using the Trusted Identity Provider
  2. That all users in are included
  3. That all groups in groups included
  4. You have mapped the Claim User Identifier (SPS-ClaimID) to the userPrincipalName LDAP attribute, according to our mappings in AD FS
  5. That you have ran a full synchronization

Web applications

Now that you have configured SharePoint services you can enable trusted identity on your web applications.

  1. Open SharePoint Central Administration and go to Manage web applications
  2. Select the web application and click Authentication Providers
  3. For the extended zone (e.g. internet), deselect Windows Authentication and select Trusted Identity Provider
  4. Click Save at the bottom of the dialog
  5. Repeat for all applicable web applications

When browsing to SharePoint, you should now be redirected to AD FS to sign in.

Office Online Server

If using Office Online Server, ensure that:

  • External access is configured for HTTPS
  • It can resolve SharePoint’s default alternate access mapping, in this example: http://sharepoint.local

Known issues

LDAPCP current has an issue with augmenting user claims with nested group memberships. This can lead permissions missing when using Check Permissions from site settings or in OAuth scenarios. At time of writing a fix is still in development.

Special thanks

Yvan Duhamel (Microsoft Escalation Engineer), for LDAPCP and his expertice in SharePoint Server authentication. We highly recommend that you check out his GitHub and LinkedIn profiles for excellent resources.