1

Sitecore 10.2:

I followed the documentation as described here.

Configuration applied to Identity Server and stored at C:\identity\config\sitecore.identityserver.devex.xml

<?xml version="1.0" encoding="utf-8"?>
<Settings>
  <Sitecore>
    <IdentityServer>
      <Clients>
        <CliServerClient>
            <ClientId>SitecoreCLIServer</ClientId>
            <ClientName>SitecoreCLIServer</ClientName>
            <AccessTokenType>0</AccessTokenType>
            <AccessTokenLifetimeInSeconds>3600</AccessTokenLifetimeInSeconds>
            <IdentityTokenLifetimeInSeconds>3600</IdentityTokenLifetimeInSeconds>
            <RequireClientSecret>true</RequireClientSecret>
            <AllowOfflineAccess>false</AllowOfflineAccess>
            <AllowedGrantTypes>
                <AllowedGrantType1>client_credentials</AllowedGrantType1>
            </AllowedGrantTypes>
            <ClientSecrets>
                <!--<ClientSecret1>PlaceholderForSuperSecret</ClientSecret1>-->
            </ClientSecrets>
            <AllowedScopes>
                <AllowedScope1>sitecore.profile.api</AllowedScope1>
            </AllowedScopes>
        </CliServerClient>
      </Clients>
    </IdentityServer>
  </Sitecore>
</Settings>

Configuration applied to Sitecore CM role and stored under ~/App_Config/Include

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentManagement">  
    <federatedAuthentication>
      <identityProviders>
        <identityProvider id="SitecoreIdentityServer">
          <transformations>
            <transformation name="admin-ify client credentials users" type="Sitecore.Owin.Authentication.Services.DefaultTransformation, Sitecore.Owin.Authentication">
              <sources hint="raw:AddSource">
                <claim name="client_id" value="SitecoreCLIServer" />
              </sources>
              <targets hint="raw:AddTarget">
                <claim name="name" value="sitecore\cliuser" />
                <claim name="http://www.sitecore.net/identity/claims/isAdmin" value="true" />
              </targets>
              <keepSource>true</keepSource>
            </transformation>
          </transformations>
        </identityProvider>
      </identityProviders>
    </federatedAuthentication>
  </sitecore>
</configuration>

After logging in I see the following username:

dotnet sitecore login --authority https://identityx.dev.sxp.local --cm https://scmsx.dev.sxp.local --allow-write true --client-credentials true --client-id SitecoreCLIServer --client-secret 'HIDDEN_FROM_BOBBY_TABLES'

Note: I found that the client secret has a limit (probably 101). I decided to use a string 64 characters long.

Unfriendly name

1 Answer 1

0

The solution is surprisingly trivial.

First we need to map the isAdmin claim to the IsAdministrator user property. More information can be found in the official docs here.

The patch configuration should contain an additional section for mapping the fields.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentManagement">
    <federatedAuthentication>
      <propertyInitializer>
        <maps>
          <map name="set IsAdministrator" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication">
            <data hint="raw:AddData">
              <source name="http://www.sitecore.net/identity/claims/isAdmin" value="true" />
              <target name="IsAdministrator" value="true" />
            </data>
          </map>
        </maps>
      </propertyInitializer>
    </federatedAuthentication>
  </sitecore>
</configuration>

Second we need to map the custom name when creating the user.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentManagement">
    <federatedAuthentication>
      <identityProvidersPerSites>
        <mapEntry name="all sites">
          <externalUserBuilder>
            <patch:attribute name="type" value="Company.Feature.Security.Services.CustomExternalUserBuilder, Company.Feature"  />
          </externalUserBuilder>
        </mapEntry>
      </identityProvidersPerSites>
    </federatedAuthentication>
  </sitecore>
</configuration>

Third we need to implement the class which manages the creation of users. Since we defined the username explicitly in the config we'll need to look for that first.

using System;
using System.Linq;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Sitecore.Diagnostics;
using Sitecore.Owin.Authentication.Identity;
using Sitecore.Owin.Authentication.Services;
using Sitecore.SecurityModel.Cryptography;

namespace Company.Feature.Security.Services
{
    public class CustomExternalUserBuilder : DefaultExternalUserBuilder
    {
        public CustomExternalUserBuilder(ApplicationUserFactory applicationUserFactory, IHashEncryption hashEncryption) : base(applicationUserFactory, hashEncryption)
        {
            Log.Info($"Creating a new instance of {typeof(CustomExternalUserBuilder)}", this);
        }

        protected override string CreateUniqueUserName(UserManager<ApplicationUser> userManager, ExternalLoginInfo externalLoginInfo)
        {
            Log.Info($"Preparing to create a new username", this);
            Assert.ArgumentNotNull(userManager, nameof(userManager));
            Assert.ArgumentNotNull(externalLoginInfo, nameof(externalLoginInfo));
            var identityProvider = this.FederatedAuthenticationConfiguration.GetIdentityProvider(externalLoginInfo.ExternalIdentity);
            if (identityProvider == null)
            {
                throw new InvalidOperationException("Unable to retrieve an identity provider for the given identity");
            }
            
            var nameClaim = externalLoginInfo.ExternalIdentity.Claims.FirstOrDefault(x => x.Type == "name");
            if(nameClaim != null)
            {
                return nameClaim.Value;
            }

            return base.CreateUniqueUserName(userManager, externalLoginInfo);
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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