2

This is my config file for the federated authentication.

<configuration
xmlns:patch="http://www.sitecore.net/xmlconfig/"
xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<settings>
  <!-- Third party app and secret id -->
  <setting name="MRDNA.Feature.Accounts.Facebook.AppId" value="*" />
  <setting name="MRDNA.Feature.Accounts.Facebook.AppSecret" value="*" />

  <setting name="MRDNA.Feature.Accounts.Google.ClientId" value="*" />
  <setting name="MRDNA.Feature.Accounts.Google.ClientSecret" value="*" />

  <!-- Setting to enable the federation authentication -->
  <setting name="FederatedAuthentication.Enabled">
    <patch:attribute name="value">true</patch:attribute>
  </setting>
</settings>

<!-- Sitecore services registration required for the federated authentication -->
<services>
  <!--<configurator type="MRDNA.Feature.Accounts.Areas.Main.Infrastructure.Configurator.ServicesConfigurator, MRDNA.Feature.Accounts" resolve="true"/>-->
  <register serviceType="Sitecore.Abstractions.BaseAuthenticationManager, Sitecore.Kernel"
            implementationType="Sitecore.Owin.Authentication.Security.AuthenticationManager, Sitecore.Owin.Authentication"
            lifetime="Singleton" />
  <register serviceType="Sitecore.Abstractions.BaseTicketManager, Sitecore.Kernel"
            implementationType="Sitecore.Owin.Authentication.Security.TicketManager, Sitecore.Owin.Authentication"
            lifetime="Singleton" />
  <register serviceType="Sitecore.Abstractions.BasePreviewManager, Sitecore.Kernel"
            implementationType="Sitecore.Owin.Authentication.Publishing.PreviewManager, Sitecore.Owin.Authentication"
            lifetime="Singleton" />
</services>

<pipelines>
  <owin.identityProviders>
    <!-- Processors for coniguring providers. Each provider must have its own processor-->
    <processor type="MRDNA.Feature.Accounts.Areas.Main.Infrastructure.Pipelines.IdentityProviders.Facebook, MRDNA.Feature.Accounts" resolve="true" />
    <processor type="MRDNA.Feature.Accounts.Areas.Main.Infrastructure.Pipelines.IdentityProviders.Google, MRDNA.Feature.Accounts" resolve="true" />
  </owin.identityProviders>
  <owin.cookieAuthentication.signedIn>
    <processor type="MRDNA.Feature.Accounts.Areas.Main.Infrastructure.Pipelines.SignedIn.TrackSignedIn, MRDNA.Feature.Accounts" resolve="true" />
  </owin.cookieAuthentication.signedIn>
</pipelines>


<federatedAuthentication type="Sitecore.Owin.Authentication.Configuration.FederatedAuthenticationConfiguration, Sitecore.Owin.Authentication">

  <!-- List of identity providers -->
  <identityProviders hint="list:AddIdentityProvider">
    <!-- Facebook provider -->
    <identityProvider id="Facebook" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
      <param desc="name">Facebook</param>
      <param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
      <caption>Facebook</caption>
      <domain>extranet</domain>
      <triggerExternalSignOut>false</triggerExternalSignOut>
      <transformations hint="list:AddTransformation" />
    </identityProvider>

    <!-- Google provider -->
    <identityProvider id="Google" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
      <param desc="name">Google</param>
      <param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
      <caption>Google</caption>
      <domain>extranet</domain>
      <triggerExternalSignOut>false</triggerExternalSignOut>
      <transformations hint="list:AddTransformation" />
    </identityProvider>
  </identityProviders>

  <!--Provider mappings to sites-->
  <identityProvidersPerSites hint="list:AddIdentityProvidersPerSites">
    <mapEntry name="provider entry" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication" resolve="true">
      <sites hint="list">
        <site>main</site>
      </sites>

      <!-- Registered identity providers for above providers -->
      <identityProviders hint="list:AddIdentityProvider">
        <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='Facebook']" />
        <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='Google']" />
      </identityProviders>
      <!--<externalUserBuilder type="MRDNA.Feature.Accounts.Areas.Main.Infrastructure.Builder.CustomProviderUserBuilder, MRDNA.Feature.Accounts" resolve="true">
        <param desc="isPersistentUser">false</param>
      </externalUserBuilder>-->
      <externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication" resolve="true">
        <IsPersistentUser>false</IsPersistentUser>
      </externalUserBuilder>
    </mapEntry>
  </identityProvidersPerSites>

  <!--List of all shared transformations-->
  <sharedTransformations/>

  <!--Property mappings initializer-->
  <propertyInitializer type="Sitecore.Owin.Authentication.Services.PropertyInitializer, Sitecore.Owin.Authentication">

    <!--List of property mappings
            Note that all mappings from the list will be applied to each providers-->
    <maps hint="list">
      <map name="email claim" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication" resolve="true">
        <data hint="raw:AddData">
          <source name="email" />
          <target name="Email" />
        </data>
      </map>
      <map name="full_name" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication" resolve="true">
        <data hint="raw:AddData">
          <source name="full_name" />
          <target name="FullName" />
        </data>
      </map>
    </maps>
  </propertyInitializer>
</federatedAuthentication>


</sitecore>
</configuration>

This is my custom provider for google

public class Google : IdentityProvidersProcessor
{
    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="Google"/> class.
    /// </summary>
    /// <param name="federatedAuthenticationConfiguration"></param>
    /// <param name="cookieManager"></param>
    /// <param name="settings"></param>
    public Google(FederatedAuthenticationConfiguration federatedAuthenticationConfiguration,
                    ICookieManager cookieManager,
                    BaseSettings settings)
                    : base(federatedAuthenticationConfiguration, cookieManager, settings)
    {
    }

    #endregion

    #region Class Variables

    protected override string IdentityProviderName => "Google";

    #endregion

    protected override void ProcessCore(IdentityProvidersArgs args)
    {
        Assert.ArgumentNotNull(args, nameof(args));

        var identityProvider = this.GetIdentityProvider();
        var authenticationType = this.GetAuthenticationType();

        var options = new GoogleOAuth2AuthenticationOptions
        {
            Caption = identityProvider.Caption,
            AuthenticationType = authenticationType,
            AuthenticationMode = AuthenticationMode.Passive,
            ClientId = Settings.GetSetting("MRDNA.Feature.Accounts.Google.ClientId"),
            ClientSecret = Settings.GetSetting("MRDNA.Feature.Accounts.Google.ClientSecret"),
            Provider = new GoogleOAuth2AuthenticationProvider
            {
                OnAuthenticated = context =>
                {
                    context.Identity.ApplyClaimsTransformations(new TransformationContext(this.FederatedAuthenticationConfiguration, identityProvider));
                    AddClaim(context, "full_name", "name");
                    AddClaim(context, "email", "email");

                    return Task.CompletedTask;
                }
            },
            Scope =
            {
                "https://www.googleapis.com/auth/userinfo.profile",
                "https://www.googleapis.com/auth/userinfo.email"
            }
        };
        GoogleAuthenticationExtensions.UseGoogleAuthentication(args.App, options);
    }

    #region Subroutines

    private void AddClaim(GoogleOAuth2AuthenticatedContext context, string claimName, string propertyName)
    {
        var value = context.User[propertyName]?.ToString();
        if (propertyName == "picture")
        {
            value = context.User["picture"]?["data"]?["url"]?.ToString();
            if (value == null)
                return;
            context.Identity.AddClaim(new Claim("picture_url", value));
            context.Identity.AddClaim(new Claim("picture_mime", "image/jpg"));
            return;
        }

        if (value == null)
            return;
        context.Identity.AddClaim(new Claim(claimName, value));
    }

    #endregion
}

This is my trackSigenIn pipeline processor

public class TrackSignedIn : SignedInProcessor
{
    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="TrackSignedIn"/> class.
    /// </summary>
    /// <param name="accountService">The account service</param>
    /// <param name="federatedAuthenticationConfiguration">The federated authentication configuration</param>
    public TrackSignedIn(IAccountService accountService, FederatedAuthenticationConfiguration federatedAuthenticationConfiguration)
    {
        this.FederatedAuthenticationConfiguration = federatedAuthenticationConfiguration;
        this.AccountService = accountService;
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets the federated authentication configuration.
    /// </summary>
    /// <value>
    /// The federated authentication configuration.
    /// </value>
    private FederatedAuthenticationConfiguration FederatedAuthenticationConfiguration { get; }

    /// <summary>
    /// Gets the account service.
    /// </summary>
    /// <value>
    /// The account service.
    /// </value>
    private IAccountService AccountService { get; }

    #endregion

    public override void Process(SignedInArgs args)
    {
        //Do not track the user signin if this is a response to a membership provider login
        var claimIdentity = args.Context.Identity;
        var provider = this.GetProvider(claimIdentity);
        if (provider.Name == Constants.LocalIdentityProvider || provider.Name == "SitecoreIdentityServer")
        {
            return;
        }
        var name = claimIdentity.Claims.First(c => c.Type.Equals("full_name")).Value;
        var email = claimIdentity.Claims.First(c => c.Type.Equals("email")).Value;
        var idp = claimIdentity.Claims.First(c => c.Type.Equals("idp")).Value;
        var innerUser = args.User.InnerUser;
        var userName = $"{innerUser.Domain.Name}\\{innerUser.Profile.Email}-{DateTime.Now.Ticks}";
        this.AccountService.LoginBySocialConnector(email, name, idp, args.User.InnerUser);
    }

    private IdentityProvider GetProvider(ClaimsIdentity identity)
    {
        return this.FederatedAuthenticationConfiguration.GetIdentityProvider(identity);
    }
}

But when i am login more than two time using google or facebook i am getting issue The maximum number of simultaneously active (logged-in) editors exceeded. The User google\ci2ZOx1G7L cannot be logged in to the system. The maximum of editors allowed by license is 2. So why it is getting logged in as interface user not as normal virtual user? Any clue

4
  • try creating a new domain and map in config file instead of extranet. your license restricts only 2 sitecore users – Abhay Dhar Feb 19 '20 at 7:26
  • I tried with facebook and gmail domain but still getting the same issue. – Durgesh Gupta Feb 19 '20 at 7:36
  • I had implemented fed auth for Azure ADb2C similar way - sitecore.stackexchange.com/questions/22947/… has the code base and config files. Probably might help you – Abhay Dhar Feb 19 '20 at 10:02
  • Any luck finding the fix? We have the same issue on Sitecore 9.3 while logging external users with AD B2C :( [Please treat it as a comment as i don't have enough reputation to add one] – damary Mar 27 '20 at 13:03