Enable federated authentication and configure Auth0 as an identity provider in Sitecore 9.0

Sitecore 9.0 has shipped and one of the new features of this new release is the addition of a federated authentication module. I wrote a module for Sitecore 8.2 in the past (How to add support for Federated Authentication and claims using OWIN), which only added federated authentication options for visitors. Backend functionality was a lot harder to integrate, but I am glad that Sitecore took the challenge and solved it for both the front- and backend. It means that I can get rid of the old code and finally can use the out of the box solution provided by Sitecore. They created a very pluggable solution which can basically register any kind of authentication module via the OWIN middleware. This blogpost will show how I integrated the Identity broker Auth0 with Sitecore. Auth0 is a platform which can act as an Identity Broker: it offers solutions to connect multiple identity providers via a single connection. Code is available at my github repository:

PS: in this example I use Auth0 as Identity broker for Facebook and Google. It’s of course possible to connect directly to Google and Facebook, I just chose not to do this.

Enable federated authentication

At first sight, getting federated authentication in the Sitecore context to work looks a bit complex, but in the end, it’s just a bit of configuration, a few lines of code and configuring the OWIN middleware. Martina Welander did a great job to document the steps to create your own provider, but some small examples always help, right?  In the end, you’ll end up with some extra login options, for example with this Auth0 variant:

Create an application in Auth0

Two connections have already been created for Facebook and Google, which can be used to authenticate via Auth0. They offer multiple different options, but for the sake of simplicity, I will stick to these. If you want to know how to configure these: the Auth0 documentation is outstanding!

To create a new provider for Sitecore, the first step would be to register a new client:

As we are integrating Auth0 with Sitecore, “Regular Web Application” should be chosen as client type.

After the client has been created, navigate to the settings tab. This overview will contain all information that is needed to configure the provider in Sitecore.

Take note of the ClientId, ClientSecret and domain. These will be needed in the Sitecore configuration to connect to the authentication endpoint. However, one setting has to be provided by the developer: the callback url has to be added. This will be <hostname> + “/signin-” + <identityprovidername>, This is https://xp0.sc/signin-auth0 in this example.

In the “Connections” – tab I already selected Facebook and Google as external Identity providers. Please take note that I also enabled another kind of login: Auth0 offers its own user database as well.

That’s all that was need to setup a new client.

Write the code

Coding is not too much of a hassle and is identical to how you would register middleware in a regular ASP.Net application. The difference is that a pipeline should be used in which the authentication middleware can be registered.

The IdentityProviderPipeline processor must inherit from the “IdentityProvidersProcessor“-class and return a unique IdentityProvidername. The overridden “ProcessCore” contains code to actually load the middleware. In a regular ASP.Net application, the OWIN middleware would have been registered in the startup class, but in this case the middleware needs to be registred in the pipeline. The ProcessCore functionparameter “IdentityProviderArgs” exposes the App property, which in fact has the IAppBuilder interface.

Adding the Middleware is business as usual: register the middleware and you’re good to go. Important to know is that the claims transformation must be executed explicitly after the user has been authenticated.

Wiring it all together

The last part is to configure the new identityprovider, which consists of a few steps:

  • Register the OWIN Authenticationprovider middleware pipeline
  • Define for which sites an identityprovider needs to registered
  • Define the identityprovider itself and configure the claim mappings

But just adding configuration isn’t enough. As this kind of authentication is completely different from the default authentication, federated authentication must be explicitly enabled.

Enable the federated authentication module

As the technique behind the authentication is completely different as opposed to the default authentication provider, Sitecore made the authenticationmanager injectable with an owin based version. To get it to work, enable the \Include\examples\ Sitecore.Owin.Authentication.Enabler.config patch-file. This patchfile will inject a different AuthanticationManager, which supports OWIN authentication modules.

 

Register the AuthenticationProvider middleware pipeline

This is basically one line of configuration; the pipeline which registers the middleware needs to be added here.

Define for which sites an identityprovider needs to registered

Within the federatedAuthentication node, the authentication providers need to be attached to the sites in which they can be used. This will make the authentication endpoint available to those sites.

Define the identityprovider itself

And last, but not least, the identity provider itself needs to be registered. In this section, the name of the provider will be registered, for what Sitecoredomain the provider will be registered and how claims should be transformed. In the included example, the role Sitecore\Developer will be added if the idp is equal to Auth0. On it’s turn, the role-claim “Sitecore\Developer” will be mapped to the Sitecore-role “Sitecore\Developer”. Although my advice would be to provide those roles within your Identity management solution, if possible, it’s a very welcome solution for  the cases when those are not available.

Bonus: Map user properties

As the Administrator role isn’t a real role, but more a Sitecore user property, this “role” needs to be set in a different way. The Propertyinitializer can be used to achieve this. First, it reads a claim (and its value) and if that claim has the defined value, the property will be set:

Conclusion

Sitecore did an awesome job on integrating federated authentication within Sitecore. All the OWIN authentication middleware that exists can be used without any modification and is easily integrated within Sitecore. A very flexible solution has been created which will make Sitecore again a little bit more mature.

22 thoughts on “Enable federated authentication and configure Auth0 as an identity provider in Sitecore 9.0

  1. Joseph Ocena

    I tried the code you provided in the repository. Unfortunately, it does not work. I received an error as shown below. Is it related to the missing file BasLijten.FederatedAuthentication.Auth0.Settings?

    “The following errors occurred while attempting to load the app.
    – No assembly found containing an OwinStartupAttribute.
    – The discovered startup type ‘Sitecore.Owin.Startup, Sitecore.Owin, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null’ conflicts with the type ‘SolrNet.Startup, SolrNet, Version=0.4.0.2002, Culture=neutral, PublicKeyToken=null’. Remove or rename one of the types, or reference the desired type directly.
    To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of “false” in your web.config.
    To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.”

    Reply
    1. Joseph Ocena

      It works now, the web.config file in your solution overwrites the web.config file in sitecore. 🙂

      Reply
      1. Bas Lijten Post author

        Hi, thanks for the answer! I don’t have a web.config in the solution, it probably gets added when restoring the packages. Thanks for mentioning!

        Reply
  2. Pingback: All the goodies from Sym 2017 | robhabraken.nl | Sitecore blog

  3. christian

    Work like a charm! Thanks. Tell me did you try to make LDAP worked with sitecore 9? we could use the ad module in sitecore 7-8 but doesn’t exist anymore.. 🙁

    Thanks,

    Reply
  4. Vyacheslav Pritykin

    Great post!

    I would just update this:

    ClaimsIdentity identity = context.Identity;
    foreach (Transformation current in identityProvider.Transformations)
    {
    current.Transform(identity, new TransformationContext(FederatedAuthenticationConfiguration, identityProvider));
    }

    into this:

    using Sitecore.Owin.Authentication.Extensions;

    context.Identity.ApplyClaimsTransformations(new
    TransformationContext(this.FederatedAuthenticationConfiguration, identityProvider));

    Reply
  5. Raj

    Thanks, wonderful article. I am able to loing using google but not able to save the username and email automatically by configuring ispersistence to true. Though the user is created in sitecore, the fullname and email fields are empty. Is there any way to achieve that.

    Reply
  6. Pingback: Sitecore 9 : Content Editors Federated Authentication with Gmail | rdhaundiyal

  7. Faiyaz

    How is that a separate link to loginwith Aouth is coming on login screen. Any customisation needed on Login screen as in GithuB I se only .cs and config file .

    Reply
    1. Vyacheslav Pritykin

      Hi Faiyaz,
      The “getSignInUrlInfo” pipeline is used to get all proper login urls for the particular site.
      Use the Sitecore.Pipelines.GetSignInUrlInfo.GetSignInUrlInfoPipeline.Run(BaseCorePipelineManager corePipelineManager, GetSignInUrlInfoArgs args) method to let the pipeline fill the args.Result property with the collection of the Sitecore.Data.SignInUrlInfo objects. Use the SignInUrlInfo.Href to build the POST forms on your custom login page for each returned SignInUrlInfo.

      Note 1: requests to sign-in must be POST, that’s why you have to build tags with the method=POST and action=%SignInUrlInfo.Href%.

      Note 2: you might want to use the SignInUrlInfo.IdentityProvider as a class value for the html in order to apply custom styling for the sign in button.

      Reply
      1. AW

        How can I get an instance of the BaseCorePipelineManager in order to pass it to GetSignInUrlInfo?

        I tried Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService() but getting an exception…

        Reply
        1. Vyacheslav Pritykin

          The best way it to use constructor injection. Just add BaseCorePipelineManager as a parameter in a constructor of your processor or any other object that is specified in the config via type=”…, …” and sitecore will inject a proper object. Note, don’t forget to add resolve=”true” in the appropriate config node (processor or any other node, where you specify the type). Read https://doc.sitecore.net/sitecore_experience_platform/developing/developing_with_sitecore/dependency_injection for more information about DI in Sitecore.

          As for the ServiceLocator, it should also work. I don’t know why you are getting an exception. Do you call it properly? Could you show your usage and an exception?
          Btw, it’s usually better to use GetRequiredService rather than GetService.

          Reply
          1. AW

            Thanks Vyacheslav!

            I was just trying to finish testing the integration – so I wrote up a quick Razor view to test the links – this may just be the wrong way to do it though:

            @using Sitecore.Pipelines.GetSignInUrlInfo;
            @using Sitecore.DependencyInjection;
            @using Sitecore.Abstractions;
            @using Sitecore.DependencyInjection;

            @{
            var args = new GetSignInUrlInfoArgs(site: “website”, returnUrl: “/”);
            var corePipelineManager = Sitecore.DependencyInjection.ServiceLocator.ServiceProvider.GetService();
            var login = GetSignInUrlInfoPipeline.Run(corePipelineManager, args);
            }

          2. AW

            NM – I was able to get it by pulling it back into the codebehind and switching it to use the non-generic version – ServiceLocator.ServiceProvider.GetService(typeof(BaseCorePipelineManager))

            Thanks again!

          3. Vyacheslav Pritykin

            I’m glad it has started to work for you. Just a few notes:
            1. In your Razor sample you’ve forgotten to specify the type for the GetService at all.
            2. It’s possible to use generic methods like this “.GetRequiredService()”, but you need to include this namespace “Microsoft.Extensions.DependencyInjection”

          4. Vyacheslav Pritykin

            Oh, well 🙂 Now I see that the angle brackets were cut by the site parser, so my first point is irrelevant. However, in order to make you code work, add the namespace I specified in the second item.

  8. Pingback: Sitecore Federated Authentication – Part 1 – Authentication with Google and Facebook Identity Providers | .Net | Sitecore blog

  9. Pingback: Do not change global.asax in Sitecore 9! – XtremDev

Leave a Reply

Your email address will not be published. Required fields are marked *