Configure multi tenant Azure Entra ID accounts with SSO and Okta custom login page in Umbraco 13

In my Umbraco 8 admin, I have multiple customer-facing sites, each with different Azure Entra IDs for SSO, and one site with an Okta account featuring a custom login screen.

I successfully set up and configured multi-tenant Azure Entra ID accounts with SSO and an Okta custom login page in Umbraco 8 using a custom authorize filter.

Here is my solution in U8: In my custom authorize filter, I retrieve the custom AuthenticationType from the admin for a site and set up authentication at runtime. It works as expected.

Now, my project has been upgraded from Umbraco 8 to Umbraco 13, but I am facing challenges in setting up and configuring multi-tenant Azure Entra ID accounts with SSO and an Okta custom login page in Umbraco 13.

Can you please help me set up and configure multi-tenant Azure Entra ID accounts with SSO and an Okta custom login page in Umbraco 13?

I am trying to set up Azure Entra ID SSO for my customer-facing site in Umbraco 13. The Azure Entra ID authentication is successful, and I can see the claim principal and User in the context.Principal object in the Program.cs file during debug mode. However, in the surface controller, the claim principal and User are always null and Authentication also false.

What I missed in my code?

Here is my sample code sequence:

I need to implement cookie authentication.

var authenticationBuilder = builder.Services.AddAuthentication(options =>
{
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultAuthenticateScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
    options.Cookie.Name = ".SampleCookie";
    options.SlidingExpiration = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
});

builder.CreateUmbracoBuilder()
    .AddBackOffice()
    .AddWebsite()
    .AddDeliveryApi()
    .AddComposers()
    .AddSection<StaticResponseSection>()
    .AddSection<EncryptionSection>()
    .Build();
	
	
	builder.Services.AddOpenIdConnect(AuthenticateScheme, options =>
    {
        options.ClientId = ClientId;
        options.ClientSecret = ClientSecret;
        options.Authority = $"{Instance}{TenantId}/v2.0";
        options.CallbackPath = CallbackPath
        options.ResponseType = OpenIdConnectResponseType.IdToken;
        options.SaveTokens = true;
        options.Scope.Clear();
        foreach (var scope in scopes.Split(' '))
        {
            options.Scope.Add(scope);
        }
        options.SignedOutRedirectUri = PostLogoutRedirectUri;

        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateIssuerSigningKey = true,
            NameClaimType = "name",
            RoleClaimType = "roles"
        };

        options.Events = new OpenIdConnectEvents
        {
            OnTokenValidated = context =>
            {
                var claims = new List<Claim>
                    {
                        new Claim(ClaimTypes.Name, context.Principal.FindFirst("name")?.Value),
                        new Claim(ClaimTypes.Email, context.Principal.FindFirst("preferred_username")?.Value)
                    };
               
                return Task.CompletedTask;
            }
        };
    });
	
app.UseAuthentication();
app.UseAuthorization();

Hi Jaffer,

Did you referred the below documentations and examples?

For Okta -

Thank you for your response.

In my Umbraco 8 application, users access the landing page directly. If they are not authorized, they are redirected to a customized Okta login screen. This login screen was built using Webpack and has been successfully implemented and is functioning well in U8.

However, I’m encountering difficulties migrating and implementing the same logic in Umbraco 13. I need to replicate this behavior in U13.

Is this approach feasible in Umbraco 13? If so, could you please guide me on how to implement it?