> For the complete documentation index, see [llms.txt](https://dev.ucommerce.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dev.ucommerce.net/readme/backoffice-authentication.md).

# Backoffice Authentication

By default, Ucommerce automatically authenticates as a test administrator account.\
This is very useful when developing locally, so you do not have to set up authentication from the get-go. When going to production this should be changed, however, so the back office is protected from unverified use, and handle individual user permissions.\
Ucommerce leverages the [built-in ASP.NET Core authorization](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/introduction?view=aspnetcore-7.0) to restrict access to the back office API. This means that you will have to implement an ASP.NET authorization system yourself.

It is recommended that you integrate a well-known identity provider. We have examples of how it can be done using [Microsoft Entra ID](/readme/backoffice-authentication/microsoft-entra-id-example.md) and [Auth0](/readme/backoffice-authentication/auth0-authentication-example.md).

{% hint style="info" %}
We suggest that you implement an authorization system using [OpenID Connect](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/secure-net-microservices-web-applications/#authenticate-with-an-openid-connect-or-oauth-20-identity-provider) since this will enable you to use single sign-on (SSO), allowing you to share logins between Ucommerce and other OAuth-enabled applications like a CMS.
{% endhint %}

## Add an external identity provider

Ucommerce takes care of the local login session, so you need to set up a scheme that will take care of logging in the user. Additionally, Ucommerce needs an implementation of the [`IExternalClaimsMapper`](#external-claims-mapper) interface.

Use the options hook when calling `AddBackOffice()` in `program.cs`, to configure your scheme:

```csharp
var ucommerceBuilder = builder.Services.AddUcommerce(builder.Configuration)
    .AddBackOffice(securitySettings =>
        {
            // This method can be called multiple times
            securitySettings.AddExternalIdentityProvider<MyExternalClaimsMapper>(
                "MyExternalScheme",
                authenticationBuilder =>
                {
                ... // Use the AuthenticationBuilder to add your scheme
                });
            // Configure Ucommerce to use your scheme from code
            securitySettings.UseExternalIdentityProvider("MyExternalScheme");
        }
    )
    ...
```

{% hint style="warning" %}
Since Ucommerce takes care of the session cookie, you should not set cookies in your external authentication scheme.
{% endhint %}

{% hint style="info" %}
You can use the [ASP.NET configuration](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-8.0) to override the external identity provider that Ucommerce will forward to. You can define the scheme by setting the value for `Ucommerce:BackOffice:ExternalIdentityProviderScheme` to the name of one of the registered schemes. This allows you to change the provider depending on the environment. To use the built-in scheme set the value to `ucommerce-test-user`.
{% endhint %}

## External Claims Mapper

Ucommerce automatically creates and updates a local user when a user logs in via an external identity provider, so it needs a mapping of the external claims, to the local user in Ucommerce.\
To create a mapping you implement the `IExternalClaimsMapper` interface.

The interface consists of a single method `MapClaims` that must take care of the mapping from the incoming claim to an `AuthUser` object.

```csharp
using Ucommerce.Web.BackOffice.Authentication;
...

public class MyExternalClaimsMapper : IExternalClaimsMapper
{
    public Task<AuthUser> MapClaims(ClaimsPrincipal principal)
    {
        var externalId = // A claim value with a unique identifier for the user
        //e.g.
        //var externalId = principal.FindFirstValue(ClaimTypes.NameIdentifier)!;
        var name = // A claim value containing the name of the user
        var isAdmin = // A claim value indicating if the user is to be an admin
        var user = new AuthUser(externalId, name)
        {
            IsAdmin = isAdmin
        };
        return Task.FromResult(user);
    }
}
```

### AuthUser Properties

| Property   | Description                                                                      |
| ---------- | -------------------------------------------------------------------------------- |
| ExternalId | The identifier from the external provider used to identify the user in Ucommerce |
| Name       | The name of the user                                                             |
| IsAdmin    | Indicate if the user should have administrator rights                            |

## The default `ExternalClaimsMapper`

Ucommerce comes with a default claims mapper (`Ucommerce.Web.BackOffice.Authentication.ExternalClaimsMapper`) that maps claims in the following way. The keys are also defined in the `UcommerceClaimTypes` constants class.

| Property   | UcommerceClaimTypes Key | Value                                                                                                                                   |
| ---------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| ExternalId | EXTERNAL\_IDENTIFIER    | [ClaimTypes.NameIdentifier](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimtypes.nameidentifier?view=net-8.0) |
| Name       | NAME                    | [ClaimTypes.Name](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimtypes.name?view=net-8.0)                     |
| IsAdmin    | IS\_ADMIN               | "IsAdmin"                                                                                                                               |

## Related Articles

{% embed url="<https://learn.microsoft.com/en-us/aspnet/core/security/authorization/introduction?view=aspnetcore-7.0>" %}

{% embed url="<https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc>" %}

{% embed url="<https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-7.0>" %}

{% content-ref url="/pages/afGlzr37PZ2anwL1slrF" %}
[Microsoft Entra ID Example](/readme/backoffice-authentication/microsoft-entra-id-example.md)
{% endcontent-ref %}

{% content-ref url="/pages/jSskUNtNxL6cZJ7QXy5j" %}
[Auth0 Authentication Example](/readme/backoffice-authentication/auth0-authentication-example.md)
{% endcontent-ref %}
