---
title: "Configure federated authentication"
slug: "configure-federated-authentication"
abstract: "Describes how to configure federated authentication"
---
# Configure federated authentication

You [use federated authentication](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-manager/using-federated-authentication-with-sitecore.html "Using federated authentication with Sitecore") to let users log in to Sitecore through an external provider. Federated authentication requires that you configure Sitecore in a specific way, depending on which external provider you use. Configuring federated authentication involves a number of tasks:

- [Configure an identity provider](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-manager/configure-federated-authentication.html#UUID-244ef742-7eec-b4bb-761e-505b1f4caf53_section-idm53130183968568 "Configure an identity provider")
- [Sitecore user name generation](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-manager/configure-federated-authentication.html#UUID-244ef742-7eec-b4bb-761e-505b1f4caf53_id__Map_claims_and "Sitecore user name generation")
- [Map claims and roles](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-manager/configure-federated-authentication.html#UUID-244ef742-7eec-b4bb-761e-505b1f4caf53_N1614939275100 "Map claims and roles")
- [Map properties](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-manager/configure-federated-authentication.html#UUID-244ef742-7eec-b4bb-761e-505b1f4caf53_id__Map_properties "Map properties")
- [Connect a user account](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-manager/configure-federated-authentication.html#UUID-244ef742-7eec-b4bb-761e-505b1f4caf53_id__Connect_users_accounts "Connect a user account")
- [Configure virtual and persistent users](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-manager/configure-federated-authentication.html#UUID-244ef742-7eec-b4bb-761e-505b1f4caf53_id__Configure_virtual_and "Configure virtual and persistent users")
- [Generate sign-in links](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-manager/configure-federated-authentication.html#UUID-244ef742-7eec-b4bb-761e-505b1f4caf53_id__Generate_sign-in_links "Generate sign-in links")

## Configure an identity provider

You must configure the identity provider you use. How you do this depends on the provider you use. The primary use case is to use Azure Active Directory (Azure AD). [Authorize access to web applications using OpenID Connect and Azure Active Directory](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-openid-connect-code) describes how Azure AD works.

To configure an identity provider:

1. Patch the `configuration/sitecore/federatedAuthentication/identityProviders` node by creating a new node with the name `identityProvider`.
2. Enter values for the `id` and `type` attributes. The `type` must implement the abstract class `Sitecore.Owin.Authentication.Configuration.IdentityProvider`. Sitecore has a default implementation –`Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider`.
3. Under the node you created, enter values for the `param`, `caption`, `domain`, and `transformations` child nodes.
4. Under the `configuration/sitecore/federatedAuthentication/identityProvidersPerSites` node, create a new node with name `mapEntry`.
5. Enter values for the `name` and `type` attributes. The value of the `name` attribute must be unique for each entry. The `type` must be `Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry`, `Sitecore.Owin.Authentication`, or inherit from this.
6. Enter `true` as the value of the `resolve ` attribute.
7. Under the node you created, enter values for the `sites` (the list of sites where the provider(s) will work), `identityProviders` (the list of providers), and `externalUserBuilder` child nodes. Enter `true` as the value of the `resolve` attribute of each `externalUserBuilder` node.

    > [!note]
    > This also applies for SXA sites.

### Add code for the provider

You must create a new processor for the `owin.identityProviders` pipeline.

To create a new processor:

1. Inherit the `Sitecore.Owin.Authentication.Pipelines.IdentityProviders.IdentityProvidersProcessor` class.
2. Override the `IdentityProviderName` property with the name you specified for the `identityProvider` in the configuration.
3. Override the `ProcessCore` method.

### Integrate with the owin.identityProviders pipeline

Next, you must integrate the code into the `owin.identityProviders` pipeline.

For example, this sample uses Azure AD as the identity provider:

```xml
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentDelivery or ContentManagement">
    <pipelines>
      <owin.identityProviders>
        <processor type="Sitecore.Owin.Authentication.YourIdentityProviders.AzureAd, YourAssembly" resolve="true" />
      </owin.identityProviders>
    </pipelines>
  </sitecore>
</configuration>

```

## Sitecore user name generation

User names must be unique across a Sitecore instance. You cannot use user names from different external providers as Sitecore user names because this does not guarantee that the user names are unique.

The `DefaultExternalUserBuilder` class creates a sequence of user names for a given external user name. It then uses the first of these names that does not already exist in Sitecore. The values in the sequence depend only on the external username and the Sitecore domain configured for the given identity provider.

## Map claims and roles

A provider issues claims and gives each claim one or more values. Sitecore reads the claims issued for an authenticated user during the external authentication process. You can restrict access to some resources to identities (clients or users) that have only specific claims.

An external user is a user that has claims. Mapping claims to roles allows the Sitecore role-based authentication system to authenticate an external user.

To map claims to roles:

1. Add an `<identityProvider>` node to `configuration/sitecore/federatedAuthentication/identityProviders.`
2. Add a `<transformations hint="list:AddTransformation">` node to the `<identityProvider>` node.
3. Add transformation nodes as child nodes.

    For example, a transformation node looks like this:

    ```xml
    <transformation type="Sitecore.Owin.Authentication.Services.DefaultTransformation, Sitecore.Owin.Authentication">
      <sources hint="raw:AddSource">
        <claim name="groups" value="f04b11c5-323f-41e7-ab2b-d70cefb4e8d0" />
        <claim name="groups" value="40901f21-29d0-47ae-abf5-184c5b318471" />
      </sources>
      <targets hint="raw:AddTarget">
        <claim name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" value="Sitecore\Developer" />
      </targets>
      <keepSource>true</keepSource>
    </transformation>
    ```

    - The `type` must inherit from the `Sitecore.Owin.Authentication.Services.Transformation` class.
    - In this example, the transformation adds a claim with the name `http://schemas.microsoft.com/ws/2008/06/identity/claims/role` and the value `Sitecore\Developer` to those identities that have two claims with the name `group` and values `f04b11c5-323f-41e7-ab2b-d70cefb4e8d0` and `40901f21-29d0-47ae-abf5-184c5b318471` at the same time.
    - `keepSource==true` specifies that the original claims (two `group` claims, in this example) will not be removed. The default is `false`, and this means that if the transformation is successfully applied to the identity, then the original claims are replaced with the ones that are stated in the `<targets>` nodes.
    - `keepSource==true` specifies that the original claims (two `group` claims, in this example) will not be removed. In Sitecore, for `Sitecore.Owin.Authentication.Services.DefaultTransformation`, `keepSource` has a default value of `false`, meaning that if the transformation is successfully applied to the identity, the original claims are replaced with the ones that are stated in the `<targets>` nodes.

        > [!note]
        > On the Identity Server, for `Sitecore.Plugin.IdentityProviders.DefaultClaimsTransformation`, `keepSource` has a default value of `true`.

> [!note]
> If you specify claims transformations in the `sitecore/federatedAuthentication/sharedTransformations` node, these transformations are for all identity providers.

## Map properties

You must map identity claims to the Sitecore user properties that are stored in user profiles.

The `propertyInitializer` node, under the `sitecore\federatedAuthentication` node, stores a list of maps. Each map has inner source and target nodes. These nodes have two attributes: `name` and `value`. You map properties by setting the value of these properties.

If a claim matches the `name` attribute of a source node (and `value`, if specified), the `value` attribute of a user property specified by the `name` attribute of a target node is set to the value of the matched claim (if the `value` attribute is not specified in the `target` node).

For example:

```xml
<propertyInitializer type="Sitecore.Owin.Authentication.Services.PropertyInitializer, Sitecore.Owin.Authentication">
  <maps hint="list">
    <map name="status to UserStatus"
      type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication">
      <data hint="raw:AddData">
        <source name="status" value="first" />
        <target name="UserStatus" value="1" />
      </data>
    </map>
  </maps>
</propertyInitializer>

```

In this example, the source `name` and `value` attributes are mapped to the `UserStatus` target name and value `1`.

> [!important]
> If you split up your configuration files, you must add the `name` attribute to the map nodes to make sure that your nodes are unique across all the files. This is due to the way Sitecore config patching works.

## Map custom users properties

You can map custom user properties in two places where the `Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper` can store them:

- If a user is virtual, regardless of whether the property is custom or not, it is stored in the `Sitecore.Security.Accounts.User` class as `.RuntimeSettings.Properties` property.
- If a user is persistent, it is stored in the `Sitecore.Security.Accounts.User` class as `.Profile.CustomProperties` property.

For debugging or development purposes, it is possible to look at these properties but they are private properties and are not expected to be accessed directly.  

For custom functionality, where you need to access these properties, you can access them through the `Sitecore.Security.Accounts.User` class `Profile` property's indexer.  This resolves the user property from the correct location regardless of whether the user is virtual or persistent.

## Connect a user account

An account connection allows you to share profile data between multiple external accounts on one side and a persistent account on the other side. If a persisted user has roles assigned to them, federated authentication shares these with the external accounts.

Under the following circumstances, the connection to an account is automatic. Sitecore signs out the authenticated user, creates a new persistent or virtual account, and then authenticates it:

- The user is already authenticated on the site.
- The user signs in to the same site with an external provider.
- There is not already a connection between an external identity and an existing, persistent account. In ASP.NET Identity, `signInManager.ExternalSignIn(...)` then returns `SignInStatus.Failure`.

To bind the external identity to an already authenticated account, you must override the `Sitecore.Owin.Authentication.Services.UserAttachResolver` class using dependency injection. The following steps show an example of doing this:

1. Extend the `Sitecore.Owin.Authentication.Services.UserAttachResolver` class:

    ```csharp
    using System;

    using System.Threading.Tasks;

    using Microsoft.Owin;

    using Sitecore.Owin.Authentication.Services;

    using Sitecore.Text;

    namespace Sitecore.Owin.Authentication.Samples.Services

    {

        public class SampleUserAttachResolver : UserAttachResolver

        {

            public override UserAttachResolverResult Resolve(UserAttachContext context)

            {

                IFormCollection formData = Task.Run(async () => await context.OwinContext.Request.ReadFormAsync()).Result;

                string consentResult = formData["uar_action"];

                UserAttachResolverResultStatus resultStatus;

                if (Enum.TryParse(consentResult, true, out resultStatus))

                {

                    return new UserAttachResolverResult(resultStatus);

                }

                string redirectUrl = new UrlBuilder("/dialogs/consent") { ["returnUrl"] = context.ReturnUrl }.ToString();

                context.OwinContext.Response.Redirect(redirectUrl);

                return new UserAttachResolverResult(UserAttachResolverResultStatus.DelayedResolve);

            }

        }

    }
    ```

    The `Resolve` method takes `UserAttachContext` as a value argument, sends a request to the controller, and handles the answer from the controller that it calls.

2. Create an endpoint by creating an MVC controller and a layout.

    The MVC controller:

    ```csharp
    using System.Web.Mvc;

    namespace Sitecore.Owin.Authentication.Samples.Controllers

    {

        public class ConsentController : Controller

        {

            public ActionResult Index()

            {

                this.ViewBag.User = this.HttpContext.User.Identity.Name;

                this.ViewBag.ReturnUrl = this.Request.Params["ReturnUrl"];

                return this.View();

            }

        }

    }
    ```

    The layout:

    ```xml
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <title>Consent window</title>
      </head>

      <body>
        <p>
          The @ViewBag.User user is already logged in. Would you like to attach to
          the user or create new record?
        </p>

        <br />

        <form method="POST" action="@ViewBag.ReturnUrl">
          <button type="submit" name="uar_action" value="attach">Attach</button>

          <button type="submit" name="uar_action" value="new">New</button>
        </form>
      </body>
    </html>
    ```

3. Register the extended class in Sitecore by creating a new service configurator class:

    ```csharp
    using Microsoft.Extensions.DependencyInjection;

    using Sitecore.DependencyInjection;

    using Sitecore.Owin.Authentication.Samples.Services;

    using Sitecore.Owin.Authentication.Services;

    namespace Sitecore.Owin.Authentication.Samples.Infrastructure

    {

        public class ServicesConfigurator : IServicesConfigurator

        {

            public void Configure(IServiceCollection serviceCollection)

            {

                serviceCollection.AddSingleton<UserAttachResolver, SampleUserAttachResolver>();

            }

        }

    }
    ```

4. Define the created class in a custom configuration file, by adding following node under the `<sitecore>` node:

    ```xml
    <services>

      <configurator
        type="Sitecore.Owin.Authentication.Samples.Infrastructure.ServicesConfigurator, Sitecore.Owin.Authentication.Samples" />

    </services>
    ```

## Programmatic account connection management

Sitecore uses the ASP.NET Identity for account connections, so account connections are handled in an identical way to the ASP.NET Identity API:

1. Retrieve a UserManager object from the Owin context:

    ```csharp
    using Sitecore.Owin.Authentication.Extensions;

    // [...]

    IOwinContext context = HttpContext.Current.GetOwinContext();

    UserManager<ApplicationUser> userManager = context.GetUserManager();
    ```

2. Use these methods for CRUD operations:

    ```

    Task<IdentityResult> AddLoginAsync(ApplicationUser user, UserLoginInfo login);

    Task<IdentityResult> RemoveLoginAsync(ApplicationUser user, UserLoginInfo login);

    Task<IList<UserLoginInfo>> GetLoginsAsync(ApplicationUser user);

    Task<ApplicationUser> FindAsync(UserLoginInfo login);
    ```

## Configure virtual and persistent users

Sitecore supports virtual users. When you authenticate users through external providers, Sitecore creates and authenticates a virtual user with proper access rights.

However, there are some drawbacks to using virtual users. User profile data cannot be persisted across sessions, as the virtual user profile exists only as long as the user session lasts. You should therefore create a real, persistent user for each external user. When a user uses external authentication for the first time, Sitecore creates and persists a new user, and binds this user to the external identity provider and the user ID from that provider. The next time that the user authenticates with the same external provider and the same credentials, Sitecore finds the already created and persisted user and authenticates it.

### User builder

The `identityProvidersPerSites/mapEntry` node contains an `externalUserBuilder` node. Add a user builder like this:

- Specify a class that inherits from `Sitecore.Owin.Authentication.Services.ExternalUserBuilder`. The user builder is responsible for creating a Sitecore user, based on the external user info.

    The default implementation that you configure to create either persistent or virtual users is based on the `isPersistentUser` constructor parameter:

    ```xml
    <externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication">
        <IsPersistentUser>true</IsPersistentUser>
    </externalUserBuilder>
    ```

> [!note]
> When you implement the user builder, you must not use it to create a user in the database. It must only create an instance of the `ApplicationUser` class.

### Applying builder to site

Find `mapEntry` within the `identityProvidersPerSites` node of the site that you are going to define a user builder for, and specify the `externalUserBuilder` node. For example:

```xml
<mapEntry type="Sitecore.FederatedAuthentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.FederatedAuthentication">
    <sites hint="list">
        <site>shell</site>
        <site>admin</site>
        <site>website</site>
    </sites>
    <identityProviders hint="list:AddIdentityProvider">mapEntry
        <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='AzureAd']" />
        <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='IdentityServer']" />
    </identityProviders>
    <externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication">
         <IsPersistentUser>true</IsPersistentUser>
    </externalUserBuilder>
</mapEntry>

```

In the example above, Sitecore applies the builder to the `shell`, `admin`, and `websites` sites.

The applied builders override the builders for the relevant site(s).

## Generate sign-in links

When you have configured external identity providers for a Sitecore site, you can generate URLs for them through the `getSignInUrlInfo` pipeline. This pipeline retrieves a list of sign-in URLs with additional information for each corresponding identity provider in this list.

> [!important]
> You must only use sign-in links in POST requests.

To generate sign-in links:

- Use the `getSignInUrlInfo` pipeline as in the following example:

    ```csharp
    using Sitecore.Pipelines.GetSignInUrlInfo;
    /*
    [...]
    */
    var args = new GetSignInUrlInfoArgs(site: "website", returnUrl: "/");
    GetSignInUrlInfoPipeline.Run(corePipelineManager, args);
    ```

The `args.Result` contains a collection of `Sitecore.Data.SignInUrlInfo` objects. These objects have the following properties:

- `Href` – the URL.
- `IdentityProvider` – the name of the identity provider. You could, for example, use it as a CSS class for a link.
- `Caption` – the caption of the identity provider. You should use this as the link text.

> [!note]
> Use the Sitecore dependency injection to get an implementation of the `BaseCorePipelineManager` class.