Contact Us

We have already discussed Sitecore Identity Server and the way to Integrate Azure Active Directory with Sitecore Identity Server in this blog

Just like Azure Active Directory, Sitecore supports extending the Identity Server to include other External Providers that support OAuth. In this blog, we discuss how we can integrate Google with the Sitecore Identity Server.

Setting Up Google Authorization

  1. Login to https://console.developers.google.com/ with you Google Account.
  2. If you want to use an existing project, skip to step 6.
  3. Click on Select Project on top to create a new project or select an existing one.
  4. 1 (11)

  5. Click on the New Project button on the right corner of the popup.
  6. Provide Project Name and click Create,/strong>
  7. 2 (7)

  8. With your project selected at the top, click on OAuth Consent Screen OAuth Consent Screen
  9. 3 (11)

  10. Setup the Consent Screen with the required info. Make sure you add your Identity Server Hostname to Authorized Domains.
  11. 4 (8)

  12. Once the Consent Screen is set up, Select Credentials in APIs & Services pane.
  13. Click on + Create Credentials and select OAuth Client ID
  14. Select Application Type as Web Application, provide a name to the application and add your Sitecore Identity Server’s domain in Authorized Redirect URIs. Click Create.
  15. 4 (8)

    Make sure to add “/callback” at the end of Identity Server URL as we are going to use that as a call back path in code.

  16. Save the Client ID and Client Secret shown in popup as those would be required in code.
  17. 5 (8)

Setting Up Sitecore Identity Server

Open the Sitecore Identity Server directory and perform the following steps:

  1. Create a new folder /sitecore/ and new file /sitecore//Sitecore.Plugin.manifest inside it. This file contains information about the Assembly where the code for our custom plugin is written.
  2.  

    <?xml version="1.0" encoding="utf-8"?>

    <SitecorePlugin PluginName="Sitecore.Plugin.IdentityProvider.Custom" AssemblyName="Sitecore.Plugin.IdentityProvider.Custom" Version="1.0.0">

      <Dependencies>

        <Dependency name="Sitecore.Plugin.IdentityProviders">3.0.0- r00211</Dependency>

      </Dependencies>

      <Tags>

        <Sitecore>Sitecore</Sitecore>

      </Tags>

    </SitecorePlugin>

  3. Create a new directory /sitecore//Config and create a new file /sitecore//Config/.xml inside it. This file contains information about the Identity provider (credentials, claims etc.)
  4.  

    <?xml version="1.0" encoding="utf-8"?>

    <Settings>

      <Sitecore>

        <ExternalIdentityProviders>

          <IdentityProviders>

            <Google type="Sitecore.Plugin.IdentityProviders.IdentityProvider, Sitecore.Plugin.IdentityProviders">

                                    <AuthenticationScheme>Google</AuthenticationScheme>      

              <DisplayName>Sign-in with Google</DisplayName>

                                    <Authority>https://accounts.google.com/</Authority>

                                    <CallbackPath>/</CallbackPath>

                    <Enabled>true</Enabled>

                                    <ClientId>YourClientID</ClientId>

                                    <ClientSecret>c_KQqx_uuU54te_KzsnaLkcM</ClientSecret>

              <ClaimsTransformations>

                <ClaimsTransformation1 type="Sitecore.Plugin.IdentityProviders.DefaultClaimsTransformation, Sitecore.Plugin.IdentityProviders">

                  <SourceClaims>

                    <Claim1 type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" />

                  </SourceClaims>

                  <NewClaims>

                    <Claim1 type="email" />

                  </NewClaims>

                </ClaimsTransformation1 >

                <ClaimsTransformation2 type="Sitecore.Plugin.IdentityProviders.DefaultClaimsTransformation, Sitecore.Plugin.IdentityProviders">

                  <SourceClaims>

                    <Claim1 type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" />

                  </SourceClaims>

                  <NewClaims>

                    <Claim1 type="name" />

                  </NewClaims>

                </ClaimsTransformation2>

                                   &n bsp;             <ClaimsTransformation3 type="Sitecore.Plugin.IdentityProviders.DefaultClaimsTransformation, Sitecore.Plugin.IdentityProviders">

                  <SourceClaims>

                    <Claim1 type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/picture" />

                  </SourceClaims>

                  <NewClaims>

                    <Claim1 type="picture" />

                  </NewClaims>

                </ClaimsTransformation3>

                                   &n bsp;            

                <GoogleEmailTransformation type="Sitecore.Plugin.IdentityProviders.DefaultClaimsTransformation, Sitecore.Plugin.IdentityProviders">

                    <SourceClaims>

                                   &n bsp;                                            <Claim1 type="http://www.sitecore.net/identity/claims/originalIssuer" value="https://accounts.google.com" />

                    </SourceClaims>

                    <NewClaims>

                        <Claim1 type="http://www.sitecore.net/identity/claims/isAdmin" value="true"/>

                    </NewClaims>

                                   &n bsp;             </GoogleEmailTransformation>

              </ClaimsTransformations>

            </Google>

          </IdentityProviders>

        </ExternalIdentityProviders>

      </Sitecore>

    </Settings>

     

NOTE: <CallbackPath> should contain the same path that we provided in step 10 of setting up Google Authorization

Setting Up The Solution

In this section, we will create a solution that will help us connect to Google and get the account information back.

  1. Create a new .Net Standard 2.0 Project.
  2. Create a new file GoogleIdentityServer.cs. This file will contain the properties that we want to pull from the configs created in section Setting Up Identity Server.
  3. namespace Sitecore.Plugin.IdentityProvider.Custom

    {

        class GoogleIdentityProvider : IdentityProviders.IdentityProvider

        {

            public string ClientId { get; set; }

            public string ClientSecret { get; set; }

            public string Authority { get; set; }

            public string CallbackPath { get; set; }

        }

    }

  4. Create a new file GoogleAppSettings.cs. This file will contain the information about the configuration section which will be used for setting up the google identity provider.
  5.  

    namespace Sitecore.Plugin.IdentityProvider.Custom.Configuration

    {

        class GoogleAppSettings

        {

            public static readonly string SectionName = "Sitecore:ExternalIdentityProviders:IdentityProviders:Google";

            public GoogleIdentityProvider GoogleIdentityProvider { get; set; } = new GoogleIdentityProvider();

        }

    }

     

    NOTE: The highlighted should match the configuration node we created in step 2 of Setting Up Identity Server.

  6. Create a new file ConfigureSitecore.cs. This will contain the code for appending Google Authentication to Sitecore.
  7.  

    using Microsoft.AspNetCore.Authentication;

    using Microsoft.AspNetCore.Authentication.OpenIdConnect;

    using Microsoft.Extensions.Configuration;

    using Microsoft.Extensions.DependencyInjection;

    using Microsoft.Extensions.Logging;

    using Sitecore.Framework.Runtime.Configuration;

    using Sitecore.Plugin.IdentityProvider.Custom.Configuration;

    using System;

    using System.Security.Claims;

    using System.Threading.Tasks;

     

    namespace Sitecore.Plugin.IdentityProvider.Custom

    {

        public class ConfigureSitecore

        {

            private readonly ILogger<ConfigureSitecore> _logger;

            private readonly GoogleAppSettings _googleAppSettings;

     

            public ConfigureSitecore(ISitecoreConfiguration scConfig, ILogger<ConfigureSitecore> logger)

            {

                this._logger = logger;

                this._googleAppSettings = new GoogleAppSettings();

                scConfig.GetSection (GoogleAppSettings.SectionName);           

            }

     

            public void ConfigureServices(IServiceCollection services)

            {

                var authenticationBuilder = new AuthenticationBuilder(services);

     

                var googleProvider = this._googleAppSettings.GoogleIdentityProvider;

                if (googleProvider.Enabled)

                {

                    authenticationBuilder

                        .AddOpenIdConnect (googleProvider.AuthenticationScheme,

                            googleProvider.DisplayName, (Action<OpenIdConnectOptions>)(options =>

                            {

                                options.SignInScheme = "idsrv.external";

                                options.SignedOutRedirectUri = "https://demo.googleidentityserver.is/Account/Logout";

                                options.ClientId = googleProvider.ClientId;

                                options.ClientSecret = googleProvider.ClientSecret;

                                options.Authority = googleProvider.Authority;

                                options.CallbackPath = googleProvider.CallbackPath;

                                options.Events.OnRedirectToIdentityProvider += (Func<RedirectContext, Task>)(context =>

                                {

                                    Claim first = context.HttpContext.User.FindFirst("idp");

                                    if (string.Equals(first != null ? first.Value : (string)null,

                                   &n bsp;    googleProvider.AuthenticationScheme, StringComparison.Ordinal))

                                   &n bsp;    context.ProtocolMessage.Prompt = "select_account";

                                    return Task.CompletedTask;

                                });

                                options.Events.OnRedirectToIdentityProviderForSignOut = context =>

                                {

                                    var logoutUri = "https://demo.googleidentityserver.is/Account/Logout";

                                    context.Response.Redirect (logoutUri);

                                    context.HandleResponse();

     

                                    return Task.CompletedTask;

                                };

                            }));

                }

            }

        }

    }

     

     

  8. Build the solution and deploy the .dll to the IdentityServer/

Result

After completing the steps, you should be able to see the button for signing in with Google.

9 (3)

Clicking on Sign-in with Google that will redirect users to Google for authentication.

10 (2)

Upon successful login, the user will be redirected to the Sitecore Launchpad.

11 (2)

Note: The claims transformation setup in Step 2 of Setting Up Identity Server is necessary for logging in otherwise you will get the following error.

12 (3)

Note: To set up the username properly, you need to override DefaultExternalUserBuilder otherwise Sitecore will assign a random username to the new users.

namespace Sitecore.Plugin.IdentityProvider.UserBuilder

{

    public class CustomUserBuilder : DefaultExternalUserBuilder

    {

        public CustomUserBuilder (ApplicationUserFactory applicationUserFactory, IHashEncryption hashEncryption) : base (applicationUserFactory, hashEncryption) { }

        protected override string CreateUniqueUserName(UserManager<ApplicationUser> userManager, ExternalLoginInfo externalLoginInfo)

        {

            if (externalLoginInfo != null)

            {

                if (!string.IsNullOrWhiteSpace(externalLoginInfo.Email))

                {

                    return externalLoginInfo.Email;

                }

                var validUserName = externalLoginInfo.DefaultUserName.Replace(",", "");

                return "sitecore\\" + validUserName.Replace(" ", "");

            }

            return "nullUserInfo";

        }

    }

}

Need Help?