0

We have added identity provider for Azure B2C for login into sitecore websites. We need to change the username of virtual user that is created by sitecore after authentication. For that, below code is added and an entry is made to the config file but the code is not getting called. Please let me know what else we need to add?

Thank you in advance.

 public class CustomExternalUserBuilder : ExternalUserBuilder
    {
        private readonly IHashEncryption _hashEncryption;

        public CustomExternalUserBuilder(
          ApplicationUserFactory applicationUserFactory,
          IHashEncryption hashEncryption)
        {
            Assert.ArgumentNotNull((object)applicationUserFactory, nameof(applicationUserFactory));
            Assert.ArgumentNotNull((object)hashEncryption, nameof(hashEncryption));
            this._hashEncryption = hashEncryption;
            this.ApplicationUserFactory = applicationUserFactory;
        }

        public bool IsPersistentUser { get; set; }

        protected ApplicationUserFactory ApplicationUserFactory { get; }

        public override ApplicationUser BuildUser(
          UserManager<ApplicationUser> userManager,
          ExternalLoginInfo externalLoginInfo)
        {
            ApplicationUser user = this.ApplicationUserFactory.CreateUser(this.CreateUniqueUserName(userManager, externalLoginInfo));
            user.IsVirtual = !this.IsPersistentUser;
            user.Email = externalLoginInfo.Email;
            return user;
        }

        protected virtual string CreateUniqueUserName(
          UserManager<ApplicationUser> userManager,
          ExternalLoginInfo externalLoginInfo)
        {
            Assert.ArgumentNotNull((object)userManager, nameof(userManager));
            Assert.ArgumentNotNull((object)externalLoginInfo, nameof(externalLoginInfo));
            var identityProvider = this.FederatedAuthenticationConfiguration.GetIdentityProvider(externalLoginInfo.ExternalIdentity)
                                   ?? throw new InvalidOperationException("Unable to retrieve an identity provider for the given identity");
            string domain = (identityProvider).Domain;
            string accountName = externalLoginInfo.ExternalIdentity?.FindFirst("AccountName")?.Value;
            string userName = $"{domain}\\{accountName}";
            return userName;
        }
    }

Config -

<configuration>
  <sitecore>
    <federatedAuthentication>
      <identityProvidersPerSites>
        <mapEntry name="portal" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication" resolve="true">
          <sites hint="list">
            <site>portal</site>
          </sites>
          <identityProviders hint="list:AddIdentityProvider">
            <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='AzureAdB2C']"/>
          </identityProviders>
          <externalUserBuilder type="Portal.SC.Feature.Login.Pipelines.Owin.CustomExternalUserBuilder, Portal.SC.Feature.Login" resolve="true">
            <param desc="isPersistentUser">false</param>
          </externalUserBuilder>
        </mapEntry>
      </identityProvidersPerSites>
    </federatedAuthentication>
  </sitecore>
</configuration>
7
  • If you override BuildUser will this get called?
    – Jeroen
    Commented Sep 15, 2021 at 15:15
  • Hi @Jeroen Thank you for your comment. Could you please elaborate exactly what we need to change here?
    – NewbieHere
    Commented Sep 15, 2021 at 15:54
  • 1
    I'm doing this on Sitecore 10 and in my case CreateUniqueUserName does not get called either but instead we have public override ApplicationUser BuildUser(UserManager<ApplicationUser> userManager, ExternalLoginInfo externalLoginInfo) which gets called and builds user. I would try to add this method in and see if it gets called.
    – Jeroen
    Commented Sep 15, 2021 at 16:50
  • 1
    @NewbieHere You'll need to create your class extending DefaultExternalUserBuilder like this --> CustomExternalUserBuilder : DefaultExternalUserBuilder Commented Sep 16, 2021 at 5:06
  • 1
    It should be whatever gets set in ExternalUserBuilder, it shouldn't be Anonymous as the user is logged in.
    – Jeroen
    Commented Sep 29, 2021 at 15:23

1 Answer 1

0

The suggestions mentioned in the comment didn't work for us. So, instead of defining username in UserBuilder, we added a method with below code that is getting called from our Login Action -

 string userName = $"{Context.Domain.Name}\\{userId}";
                    Sitecore.Security.Accounts.User virtualUser = AuthenticationManager.BuildVirtualUser(userName, true);
                    virtualUser.SetRoles(user, account, _currentPortalId);
                    AuthenticationManager.Login(virtualUser);

This code runs without any errors and we are able to get required username in Context.User.

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.