Forum Discussion
Third party oidc authentication with SPSE failed
I've sent you the oidc discovery endpoint and jwks url for our test environment, including the configured value.
Thanks
- cangotJan 04, 2022Copper Contributor
Hi,
We are running into a similar scenario.
jinzhong he& Steve Zhang : Did you get the full SharePoint SE / KeyCloak integration working / issues faced & solutions ?
Can you please share installation steps details ?
That would be very helpful. Thanks.- Steve ZhangJan 04, 2022
Microsoft
cangot We identified the problem with Jinzhong, we will have a fix soon.
I don't have a steps for configuration in hand, but you can follow the doc we published (OpenID Connect 1.0 authentication - SharePoint Server | Microsoft Docs). It will be similar for 3rd party OIDC IDP. I think Jinzhong was following that as well.
- bdecampJan 07, 2022Copper Contributor
We're having this issue in Keycloak and Red Hat SSO (RH-SSO) as well when attempting to implement OIDC in Sharepoint Subscription Edition.
We've found the cause of the issue. It is caused by an incomplete OIDC client implementation in Sharepoint subscription edition. Sharepoint is failing to perform proper OIDC Token validation steps for the ID and Access tokens it receives. And instead depends on a manual one-time import of the signing certificate, with the administrator manually browsing to the JWKS URL to acquire the Identity providers signing certificate. This is supposed to be done dynamically by the OIDC client.
Notice this manual step in the official documentation that is required when initially configuring Sharepoint OIDC https://docs.microsoft.com/en-us/sharepoint/security-for-sharepoint-server/oidc-1-0-authentication :
"Open jwks_uri (https://login.microsoftonline.com/common/discovery/keys), and save the x5c certificate string of the first key for later use in SharePoint setup (if the first key doesn’t work, try the second or third key)."
Then later in the documentation, the manually acquired cert is used to add a new SP Trusted Identity Token Issuer:# Public key of the AAD OIDC signing certificate. Please replace <x5c cert string> with the encoded cert string which you get from x5c certificate string of the keys of jwks_uri from Step #1 $encodedCertStr = <x5c cert string> $signingCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 @(,[System.Convert]::FromBase64String($encodedCertStr)) # Create a new SPTrustedIdentityTokenIssuer in SharePoint New-SPTrustedIdentityTokenIssuer -Name "contoso.local" -Description "contoso.local" -ImportTrustCertificate $signingCert -ClaimsMappings $email -IdentifierClaim $email.InputClaimType -RegisteredIssuerName $registeredissuernameurl -AuthorizationEndPointUri $authendpointurl -SignOutUrl $signouturl -DefaultClientIdentifier $clientIdentifier
Notice the ambiguity of the documentation quote that further highlights the root problem: "if the first key doesn’t work, try the second or third key". This ambiguity makes clear the fact that Sharepoint is not able to dynamically lookup the certificate to use from the JWKS URL the way OIDC specifies. The administrator performs the lookup manually during configuration. This precludes ever changing the Identity Provider signing keys, as changing the signing key would require another manual import of the new signing certificate. Changing signing keys is designed to be transparent and possible without breaking client applications per the OIDC spec.
The OIDC spec says the dynamic lookup of the certificate is done by the OIDC Client using the 'kid' value in the ID or Access Token it receives, it is supposed to compare the kid value to the list of certificates provided by the identity provider at the JWKS URL to dynamically discover the x5c certificate to use for the validation. This step is entirely skipped by Sharepoint Subscription Edition.
The only reason OIDC works at all in Sharepoint Subscription Edition, and only when using ADFS or Azure AD, is from these coincidental behaviors:
1. The signing cert is manually imported in advance by the administrator by interactively visiting the JWKS URL of the Identity Provider, and manually providing that certificate to New-SPTrustedIdentityTokenIssuer powershell command. But even this manual step results in ambiguous results per the documentation: "if the first key doesn’t work, try the second or third key". As there may be multiple signing certificates in use by the IdP.
2. ADFS and Azure AD always use the x5t thumbprint of the signing certificate as the kid value (key id). This allows sharepoint to simply match the kid value from the ID or Access Token to the thumbprint of the certificate in sharepoint's local Certificate Trust storage, bypassing the proper OIDC spec which states sharepoint should lookup the certificate via the JWKS URL, and match the results using the kid value in the access/id token.
Even with the non OIDC compliant manual certificate import step, Keycloak still doesn't work with Sharepoint. This is further highlighting sharepoint's OIDC logic deficiency: Keycloak uses a unique GUID for the kid, instead of the x5t value (this is compliant behavior, the x5t value simply needs to be unique. ADFS and Azure AD always use x5t as the kid value, which is also compliant behavior as the x5t value is a sha1 hash, which is generally unique). So even if you perform the manual JWKS certificate import when setting up Keycloak as sharepoint OIDC Identity Provider, Sharepoint is unable to match the 'kid' value from Keycloak to its local certificate store, as sharepoint only stores the sha1 thumbprint, not the kid value from the Identity Provider. Sharepoint is making the incorrect assumption that the kid value is always the sha1 thumbprint of the signing certificate, this assumption is only valid for IdP's that use the sha1 thumbprint as the kid value, as is the case with ADFS and Azure AD.
In conclusion, point 1 is the real issue that needs fixed. Sharepoint needs to follow the OIDC specification and dynamically query the JWKS URL to discover the certificates used by the Identity Provider, and then match the 'kid' value from the ID / Access Token to get the proper certificate to use for validation dynamically.
Alternatively the issue can be mostly worked-around by changing Keycloak to always use the sha1 thumbprint of the certificate as the "kid" value of OIDC tokens (would have to be done in code, it is not configurable to change the kid format in Keycloak runtime settings). But this still would require the non standard manual import of the signing certificate into sharepoint. So this work around still leaves the root problem unsolved, which is sharepoint does not dynamically lookup the JWKS URL, and instead depends on one-time administrator manual lookup and import of the signing cert from the JWKS url of the Identity Provider. This work-around also precludes the ability to ever change the signing certificate without manually re-importing the certificate and re-configuring Sharepoint from powershell. This work-around simply makes Keycloak behave like ADFS and Azure AD. If point 1 is fixed, then the work-around is no longer needed for Keycloak, as sharepoint will no longer make the assumption that the kid value always matches the cert thumbprint. It will be able to lookup the validation certificate no matter what kid format is used by an IdP.