Azure AD integration in backoffice perhaps broken in Umbraco 10?
I have added Azure AD B2C login in an Umbraco 10.2.1 installation, I followed this documentation here:
https://our.umbraco.com/Documentation/Reference/Security/Authenticate-with-Active-Directory/
Only difference is I have also added options.AuthorizationEndPoint and options.TokenEndPoint. Otherwise its the same, so I dont thinks its relevant to post the code itself as its nearly 1:1 the same.
The reason for adding AutorizationEndpoint and TokenEndPoint is because the application is setup in our Azure AD as single tenant. The documentation is for multi tenant setups (which IMO is not very good practice for the backoffice in some cases). The documentation should be expanded with this.
Either way, the issue is the authorisation process works, but once you get to the backoffice its just a blank screen. So I checked the umbracotracelog to see if I could find anything, and one exception appeared every time I used azure ad login, and not a local user:
System.ArgumentNullException: Value cannot be null. (Parameter 'culture')
at Umbraco.Cms.Core.Services.LocalizedTextService.GetAllStoredValues(CultureInfo culture)
at Umbraco.Cms.Web.BackOffice.Controllers.BackOfficeController.LocalizedText(String culture)
at lambda_method102(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Umbraco.Cms.Web.Common.Middleware.BasicAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Cms.Web.BackOffice.Middleware.BackOfficeExternalLoginProviderErrorMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at SixLabors.ImageSharp.Web.Middleware.ImageSharpMiddleware.Invoke(HttpContext httpContext, Boolean retry)
at StackExchange.Profiling.MiniProfilerMiddleware.Invoke(HttpContext context) in C:\projects\dotnet\src\MiniProfiler.AspNetCore\MiniProfilerMiddleware.cs:line 119
at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Cms.Web.Common.Middleware.PreviewAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Umbraco.Cms.Web.Common.Middleware.UmbracoRequestLoggingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
I thought perhaps a claim was missing, but there is no such claim from azure ad with the name "culture".
So what could be wrong? To me it seems there is a bug in umbraco but I could be wrong. Although I mentioned it might not be necessary to provide code, I can of course provide it if needed.
I also have an umbraco 8.17 installation with azure ad backoffice integration and that works just fine with the exact same settings in azure.
There is now a code snippet on that ticket, but it's for AddOpenIdConnect rather than AddMicrosoftAccount. Does anyone know whether that solution can be adapted?
There is no OnTokenValidated event, although there's one called OnTicketReceived but I'm not sure whether it's appropriate and I don't know how to hook into it anyway!
I'm also struggling with getting this all set up on a 10.2.1 site. I agree that the docs need to be updated* as it seems that a few things need to be manually configured before everything works.
Edit: After fiddling with a few things I've got as far as the blank screen documented in the first post (with the same "culture" error in the log).
We had been trying to follow this example and managed to get to the point that a user could authenticate, however we were unable to get the AD roles and hence we refactored things to work with OpenIdConnect which does return the roles.
The member accounts now auto create themselves based on the AD roles and update each time the members log back in.
We have done the same for the back office, however my hurdle is trying to disable a back office user, I am about to add a separate thread about that so as not to confuse things here.
If you decide to go the same route as us, let me know and I can see if I can put something together to help guide you.
That would be great. I initially fiddled with getting it to work with openidconnect, but I struggled with it and switched over the using the method as described in the OP. But alas, that really just led me to another issue obviously.
Azure AD integration in backoffice perhaps broken in Umbraco 10?
I have added Azure AD B2C login in an Umbraco 10.2.1 installation, I followed this documentation here: https://our.umbraco.com/Documentation/Reference/Security/Authenticate-with-Active-Directory/ Only difference is I have also added options.AuthorizationEndPoint and options.TokenEndPoint. Otherwise its the same, so I dont thinks its relevant to post the code itself as its nearly 1:1 the same. The reason for adding AutorizationEndpoint and TokenEndPoint is because the application is setup in our Azure AD as single tenant. The documentation is for multi tenant setups (which IMO is not very good practice for the backoffice in some cases). The documentation should be expanded with this.
Either way, the issue is the authorisation process works, but once you get to the backoffice its just a blank screen. So I checked the umbracotracelog to see if I could find anything, and one exception appeared every time I used azure ad login, and not a local user:
I thought perhaps a claim was missing, but there is no such claim from azure ad with the name "culture".
So what could be wrong? To me it seems there is a bug in umbraco but I could be wrong. Although I mentioned it might not be necessary to provide code, I can of course provide it if needed.
I also have an umbraco 8.17 installation with azure ad backoffice integration and that works just fine with the exact same settings in azure.
Hi Frederik
Im having the same problem with an adfs external login on a Umbraco 10 solution.
I dont now the answer, but I have raised a support issue with Umbraco. I will let you know if i find a solution.
Have a nice day
I have also raised it as an issue on github here: https://github.com/umbraco/Umbraco-CMS/issues/13100
There is now a code snippet on that ticket, but it's for AddOpenIdConnect rather than AddMicrosoftAccount. Does anyone know whether that solution can be adapted?
There is no OnTokenValidated event, although there's one called OnTicketReceived but I'm not sure whether it's appropriate and I don't know how to hook into it anyway!
I'm also struggling with getting this all set up on a 10.2.1 site. I agree that the docs need to be updated* as it seems that a few things need to be manually configured before everything works.
Edit: After fiddling with a few things I've got as far as the blank screen documented in the first post (with the same "culture" error in the log).
*AuthorizationEndpoint and TokenEndpoint need to be specified. The Redirect URI in Azure needs to be set to https://mysite.example.com/umbraco-signin-microsoft/.
We had been trying to follow this example and managed to get to the point that a user could authenticate, however we were unable to get the AD roles and hence we refactored things to work with OpenIdConnect which does return the roles.
The member accounts now auto create themselves based on the AD roles and update each time the members log back in.
We have done the same for the back office, however my hurdle is trying to disable a back office user, I am about to add a separate thread about that so as not to confuse things here.
If you decide to go the same route as us, let me know and I can see if I can put something together to help guide you.
That would be great. I initially fiddled with getting it to work with openidconnect, but I struggled with it and switched over the using the method as described in the OP. But alas, that really just led me to another issue obviously.
For anyone stumbling upon this thread, a couple of things:
is working on a reply...