5

In my Sitecore 9.1 installation I'm trying to use Federated Authentication and have almost successfully set it up. When I click the "log in" button on my public website I'm redirected to the OpenIDConnect site where I'm authenticating. I can see from Chrome Developer Tools that OIDC performs the postback to Sitecore with the authorization code, so the OIDC setup and authentication works. Sitecore, on the other hand, fails with Unsuccessful login with external provider.

In my log file I can see the following error:

4716 12:58:56 ERROR Unable to get and an external login info via Microsoft.Owin.Security.AuthenticationManagerExtensions.GetExternalLoginInfoAsync. 
Most probably the identity does not have a 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' claim.

According to this KB article this is because the OIDC does not provide a nameidentifier claim. The OIDC provider I'm using does not send a nameidentifier claim, so this makes sense.

That article conveniently has a solution (#1). However, that solution doesn't work!

I've added the required transformation tag, but I'm still getting Unsuccessful login with external provider!

Here's my complete configuration file:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set">
  <sitecore>
    <settings>
      <setting name="FederatedAuthentication.Enabled">
        <patch:attribute name="value">true</patch:attribute>
      </setting>
    </settings>
    <pipelines>
      <owin.identityProviders>
        <processor type="MySolution.OidcIdentityProvider, MyAssembly" resolve="true" />
      </owin.identityProviders>
    </pipelines>
    <federatedAuthentication type="Sitecore.Owin.Authentication.Configuration.FederatedAuthenticationConfiguration, Sitecore.Owin.Authentication">
      <identityProvidersPerSites hint="list:AddIdentityProvidersPerSites">
        <mapEntry name="public" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication">
          <sites hint="list">
            <site>website</site>
          </sites>
          <identityProviders hint="list:AddIdentityProvider">
            <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='MyOidc']" />
          </identityProviders>
          <externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication">
            <param desc="isPersistentUser">false</param>
          </externalUserBuilder>
        </mapEntry>
      </identityProvidersPerSites>
      <identityProviders hint="list:AddIdentityProvider">
        <identityProvider id="MyOidc" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
          <param desc="name">$(id)</param>
          <param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
          <caption>Log in with OpenIDConnect</caption>
          <icon>sitecore/shell/themes/standard/Custom/24x24/profile.png</icon>
          <domain>extranet</domain>
          <transformations hint="list:AddTransformation">
            <transformation name="Idp Claim" type="Sitecore.Owin.Authentication.Services.SetIdpClaimTransform, Sitecore.Owin.Authentication" />
            <transformation name="Name Identifier Claim" type="Sitecore.Owin.Authentication.Services.DefaultTransformation, Sitecore.Owin.Authentication">
              <sources hint="raw:AddSource">
                <claim name="sub" />
              </sources>
              <targets hint="raw:AddTarget">
                <claim name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" />
              </targets>
              <keepSource>false</keepSource>
            </transformation>
          </transformations>
        </identityProvider>
      </identityProviders>
    </federatedAuthentication>
    <federatedAuthentication>
      <identityProviders>
        <identityProvider id="SitecoreIdentityServer">
          <enabled>false</enabled>
        </identityProvider>
      </identityProviders>
    </federatedAuthentication>

    <sites>
      <site name="shell" set:loginPage="/sitecore/login"/>
      <site name="admin" set:loginPage="/sitecore/admin/login.aspx"/>
    </sites>

  </sitecore>
</configuration>

The article said to transform from the following source claim:

<sources hint="raw:AddSource">
  <claim name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" />
</sources>

But seeing as I don't have a upn claim from OIDC either, I want to convert the sub claim, which is what I set up in the above configuration.

For good measure I also tried manually starting the transformation by attaching to the SecurityTokenValidated notification in OpenIdConnectAuthenticationOptions:

protected override void ProcessCore(IdentityProvidersArgs args) {
    args.App.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions {
        Authority = "https://my.oidc",
        ClientId = "myclient",
        ClientSecret = "mysecret",
        Scope = "openid myscopes",
        RedirectUri = "https://mysite/identity/externallogincallback",
        AuthenticationType = GetAuthenticationType(),
        ResponseType = "code",
        SignInAsAuthenticationType = GetAuthenticationType(),
        UseTokenLifetime = false,
        Notifications = new OpenIdConnectAuthenticationNotifications {
            SecurityTokenValidated = OnSecurityTokenValidated
        }
    });
}

private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) {
    TransformationContext transformationContext = new TransformationContext(FederatedAuthenticationConfiguration, GetIdentityProvider());
    context.AuthenticationTicket.Identity.ApplyClaimsTransformations(transformationContext);

    return Task.CompletedTask;
}

Though this didn't help either.

The OIDC authentication and redirection obviously works, but why does Sitecore complain that identity does not have a nameidentifier claim when I've specifically said to transform the sub claim to nameidentifier, and how can I make this work?

UPDATE

After doing some more debugging I've come to the conclusion that the transform actually works. When debugging the SecurityTokenValidated notification and looking at the context.AuthenticationTicket.Identity object I can see that it now actually has the nameidentifier claim, as can be evidenced from this screenshot:

Quickwatch

The Sitecore log still complains with the same error, though:

4716 12:58:56 ERROR Unable to get and an external login info via Microsoft.Owin.Security.AuthenticationManagerExtensions.GetExternalLoginInfoAsync. 
Most probably the identity does not have a 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' claim.

So something is obviously wrong, but I still don't know what to do.

10
  • 1
    have you confirmed the claim is actually "sub"?
    – josedbaez
    Oct 2, 2019 at 12:39
  • @josedbaez Yes, the sub claim is returned in calls to /userinfo when I test with Postman
    – GTHvidsten
    Oct 2, 2019 at 12:46
  • did you try objectidentifier claim? Oct 2, 2019 at 18:17
  • @MahendraShekhawat There is no claim called objectidentifier in the claims returned from /userinfo or on the id_token or access_token
    – GTHvidsten
    Oct 2, 2019 at 21:04
  • 1
    @AmroMustafa You should probably open a new question with your specific question since yours is more related to CM/CD, while mine was not.
    – GTHvidsten
    Feb 11, 2020 at 19:02

1 Answer 1

2

It seems that the following line in my OidcIdentityProvider is what was causing my problems:

SignInAsAuthenticationType = GetAuthenticationType(),

When I removed this the full authentication flow started working! I don't know what this setting is supposed to do, but it doesn't seem to do any harm to not have it there (at least for now).

2
  • Hi GTHvidsten, I also have a the similar requirement using the OKTA provider. I am facing issue with "AuthenticationTicket" , it is coming null for. Is it possible for you the share your code with me to validate if I am missing anything. Thanks,Alok...
    – Alok Kumar
    Oct 16, 2020 at 6:13
  • I'm running into the exact same issue and I never had SignInAsAuthenticationType = GetAuthenticationType(), to begin with :worried: Nov 14, 2022 at 5:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.