Hi all,
I’m working with Umbraco 17 and currently having issues with integrating the same external login provider (i.e: Azure EntraID) to the backoffice and the frontend site.
The way the site restricts frontend access is by extending the default RenderController to have an Authorize attribute. There’s no frontend login page and the site doesn’t use Members to restrict frontend access.
The problem I’m having is that, the SSO login works fine on the frontend, but it will throw this error when accessing the backoffice (i.e: /umbraco)
{
"type": "Error",
"title": "The external login authenticated successfully but the key LoginProvider was not found in the authentication properties. Ensure you call SignInManager.ConfigureExternalAuthenticationProperties before issuing a ChallengeResult.",
"status": 500,
"detail": " at Umbraco.Cms.Web.Common.Security.UmbracoSignInManager`1.GetExternalLoginInfoAsync(String expectedXsrf)\r\n at Umbraco.Cms.Api.Management.Controllers.Security.BackOfficeController.AuthorizeExternal(OpenIddictRequest request)\r\n at Umbraco.Cms.Api.Management.Controllers.Security.BackOfficeController.Authorize(CancellationToken cancellationToken)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.\u003CInvokeActionMethodAsync\u003Eg__Logged|12_1(ControllerActionInvoker invoker)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.\u003CInvokeNextActionFilterAsync\u003Eg__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.\u003CInvokeNextResourceFilter\u003Eg__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.\u003CInvokeAsync\u003Eg__Logged|17_1(ResourceInvoker invoker)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.\u003CInvokeAsync\u003Eg__Logged|17_1(ResourceInvoker invoker)\r\n at Umbraco.Cms.Web.Common.Middleware.BasicAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.\u003C\u003Ec__DisplayClass2_0.\u003C\u003CCreateMiddleware\u003Eb__0\u003Ed.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Umbraco.Cms.Api.Management.Middleware.BackOfficeExternalLoginProviderErrorMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.\u003C\u003Ec__DisplayClass2_0.\u003C\u003CCreateMiddleware\u003Eb__0\u003Ed.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)\r\n at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)\r\n at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at Umbraco.Cms.Web.Common.Middleware.ProtectRecycleBinMediaMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.\u003C\u003Ec__DisplayClass2_0.\u003C\u003CCreateMiddleware\u003Eb__0\u003Ed.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at StackExchange.Profiling.MiniProfilerMiddleware.Invoke(HttpContext context) in C:\\projects\\dotnet\\src\\MiniProfiler.AspNetCore\\MiniProfilerMiddleware.cs:line 112\r\n at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.\u003C\u003Ec__DisplayClass2_0.\u003C\u003CCreateMiddleware\u003Eb__0\u003Ed.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Umbraco.Cms.Web.Common.Middleware.PreviewAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.\u003C\u003Ec__DisplayClass2_0.\u003C\u003CCreateMiddleware\u003Eb__0\u003Ed.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestLoggingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)\r\n at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.\u003C\u003Ec__DisplayClass2_0.\u003C\u003CCreateMiddleware\u003Eb__0\u003Ed.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.\u003CInvoke\u003Eg__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)",
"instance": "InvalidOperationException"
}
For the backoffice external login setup, I’m using exactly the same setup as per Umbraco’s documentation and using AddMicrosoftAccount() as its provider, whilst below is the setup for the frontend login:
#Program.cs
services.AddUmbraco(_env, _config)
.AddBackOffice()
.AddWebsite()
.AddDeliveryApi()
.AddComposers()
.AddAzureBlobMediaFileSystem()
.AddAzureEntraIDBackofficeAuthentication()
.Build();
services.ConfigureAzureEntraIDForFrontendAuthentication();
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = new PathString("/umbraco");
});
#Extensions.cs
public static IServiceCollection ConfigureAzureEntraIDForFrontendAuthentication(this IServiceCollection services)
{
var schemeName = BackOfficeAuthenticationBuilder.SchemeForBackOffice(AzureEntraIDBackOfficeExternalLoginProviderOptions.SchemeName);
services
.AddAuthentication(options =>
{
options.DefaultScheme = schemeName;
options.DefaultChallengeScheme = schemeName;
options.DefaultAuthenticateScheme = schemeName;
options.DefaultSignInScheme = schemeName;
options.DefaultSignOutScheme = schemeName;
});
return services;
}
Any help and suggestions are greatly appreciated.
Many thanks,
Afif







