Hi everyone,
I’m trying to update an internal website from Umbraco 13 to 17. It uses Active Directory authentication, so when a user opens /umbraco it just logs in automatically. I’m struggling to get this working in Umbraco 17.
The code I’m using is adapted from what I was doing in 13, which in turn was adapted from 10, and probably 8 before that. It might not be following current best practice ![]()
I have a file called BackofficeAuthenticationExtensions.cs as follows. I’ve added comments showing what I’ve changed from the U13 version.
using Microsoft.AspNetCore.Authentication.MicrosoftAccount;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
using Umbraco.Cms.Api.Management.Security; // Was Umbraco.Cms.Web.BackOffice.Security
namespace KnowledgeBase
{
public static class BackofficeAuthenticationExtensions
{
public static IUmbracoBuilder ConfigureAuthentication(this IUmbracoBuilder builder)
{
builder.Services.ConfigureOptions<AzureB2CBackofficeExternalLoginProviderOptions>();
builder.AddBackOfficeExternalLogins(logins =>
{
const string schema = MicrosoftAccountDefaults.AuthenticationScheme;
logins.AddBackOfficeLogin(
backOfficeAuthenticationBuilder =>
{
backOfficeAuthenticationBuilder.AddMicrosoftAccount( // Was BackOffice with a capital B
BackOfficeAuthenticationBuilder.SchemeForBackOffice(schema) ?? string.Empty,
options =>
{
options.AuthorizationEndpoint = "https://login.microsoftonline.com/MY GUID/oauth2/v2.0/authorize";
options.CallbackPath = "/umbraco-signin-microsoft/";
options.ClientId = "MY CLIENT ID";
options.ClientSecret = "MY CLIENT SECRET";
options.TokenEndpoint = "https://login.microsoftonline.com/MY GUID/oauth2/v2.0/token";
});
});
});
return builder;
}
}
public class AzureB2CBackofficeExternalLoginProviderOptions : IConfigureNamedOptions<BackOfficeExternalLoginProviderOptions>
{
public const string SchemeName = "Microsoft";
public void Configure(string? name, BackOfficeExternalLoginProviderOptions options)
{
// Was if (name != Constants.Security.BackOfficeExternalAuthenticationTypePrefix + SchemeName)
if (name != BackOfficeAuthenticationBuilder.SchemeForBackOffice(SchemeName))
{
return;
}
Configure(options);
}
public void Configure(BackOfficeExternalLoginProviderOptions options)
{
options.AutoLinkOptions = new ExternalSignInAutoLinkOptions(
autoLinkExternalAccount: true,
defaultUserGroups: new[] { "editor" }, // Was Constants.Security.EditorGroupAlias
defaultCulture: null,
allowManualLinking: false
)
{
OnAutoLinking = (autoLinkUser, loginInfo) =>
{
autoLinkUser.IsApproved = false;
},
OnExternalLogin = (user, loginInfo) =>
{
return true;
}
};
options.DenyLocalLogin = true;
// options.AutoRedirectLoginToExternalProvider = true; removed
}
}
}
As you can see, very little has changed between the working U13 version and the non-working U17 version.
My Program.cs contains .ConfigureAuthentication() just before the .Build() call. Web.config contains <requestLimits maxQueryString="8192" maxUrl="16384" />.
The issue is that when I browse to /umbraco, I get the message “Unfortunately, direct login is not possible. It has been disabled by a provider.” The log contains an authentication attempt:
{"@t":"2026-03-31T21:45:09.6254005Z","@mt":"The request URI matched a server endpoint: {Endpoint}.","@tr":"5d72fcdad7ea46da61e4e5844974d41c","@sp":"0d96d97163bb3f89","Endpoint":"Authorization","EventId":{"Id":6053},"SourceContext":"OpenIddict.Server.OpenIddictServerDispatcher","RequestId":"400003f5-0000-f700-b63f-84710c7967bb","RequestPath":"/umbraco/management/api/v1/security/back-office/authorize","ProcessId":2488,"ProcessName":"w3wp","ThreadId":3,"ApplicationId":"21f1660fa8588b317dc9e30a8881e8ad97f69792","MachineName":"BRCSVWEBT4","Log4NetLevel":"INFO ","HttpRequestId":"741c812c-dd61-4633-8121-50f44e4c6fb8","HttpRequestNumber":3,"HttpSessionId":"0"}
{"@t":"2026-03-31T21:45:09.6266188Z","@mt":"The authorization request was successfully extracted: {Request}.","@tr":"5d72fcdad7ea46da61e4e5844974d41c","@sp":"0d96d97163bb3f89","Request":"{\r\n \"redirect_uri\": \"https://kbtest.mydomain.net/umbraco/oauth_complete\",\r\n \"client_id\": \"umbraco-back-office\",\r\n \"response_type\": \"code\",\r\n \"state\": \"HXE1rFsm5N\",\r\n \"scope\": \"offline_access\",\r\n \"prompt\": \"consent\",\r\n \"access_type\": \"offline\",\r\n \"code_challenge\": \"REDACTED\",\r\n \"code_challenge_method\": \"S256\"\r\n}","EventId":{"Id":6030},"SourceContext":"OpenIddict.Server.OpenIddictServerDispatcher","RequestId":"400003f5-0000-f700-b63f-84710c7967bb","RequestPath":"/umbraco/management/api/v1/security/back-office/authorize","ProcessId":2488,"ProcessName":"w3wp","ThreadId":3,"ApplicationId":"21f1660fa8588b317dc9e30a8881e8ad97f69792","MachineName":"BRCSVWEBT4","Log4NetLevel":"INFO ","HttpRequestId":"741c812c-dd61-4633-8121-50f44e4c6fb8","HttpRequestNumber":3,"HttpSessionId":"0"}
{"@t":"2026-03-31T21:45:09.6511115Z","@mt":"The authorization request was successfully validated.","@tr":"5d72fcdad7ea46da61e4e5844974d41c","@sp":"0d96d97163bb3f89","EventId":{"Id":6031},"SourceContext":"OpenIddict.Server.OpenIddictServerDispatcher","RequestId":"400003f5-0000-f700-b63f-84710c7967bb","RequestPath":"/umbraco/management/api/v1/security/back-office/authorize","ProcessId":2488,"ProcessName":"w3wp","ThreadId":3,"ApplicationId":"21f1660fa8588b317dc9e30a8881e8ad97f69792","MachineName":"BRCSVWEBT4","Log4NetLevel":"INFO ","HttpRequestId":"741c812c-dd61-4633-8121-50f44e4c6fb8","HttpRequestNumber":3,"HttpSessionId":"0"}
So it does appear to be trying to authenticate, but there’s nothing in the log past that “successfully validated” entry. I have no idea where I’m supposed to look to figure out why it isn’t logging in.
The really bizarre thing is that this worked yesterday. I immediately checked my working code into source control, but now the same revision is failing. It was completely stable under Umbraco 13, so I’m at a complete loss here. I feel like I might have missed something obvious.
Can anyone help?
Thanks ![]()