Аутентификация с помощью Azure AD redirect_uri неверна с использованием FrontDoor

У меня есть установка Azure FrontDoor в качестве обратного прокси-сервера / балансировщика нагрузки между контейнером, работающим на порту 5443, и персональным доменом. Смысл этого в том, чтобы предоставить пользователям стандартный адрес. Т.е. на container.azurecontainer.io:3443 указывает https://oursite3.example.com/.

Один и тот же aci запускает несколько контейнеров:


    container.azurecontainer.io:443
    container.azurecontainer.io:2443
    container.azurecontainer.io:3443


    https://oursite1.example.com
    https://oursite2.example.com
    https://oursite3.example.com 

(строка 116:

Затем у нас есть несколько ACI, развернутых по всему миру в разных регионах (следовательно, мы используем Frontdoor для балансировки нагрузки между разными экземплярами).

В этом примере на container.azurecontainer.io:3443 установлена ​​аутентификация MS AD. При нажатии на ссылку пользователь перенаправляется на вход, создается ссылка, которая перенаправляет на нее браузер. В ссылке есть redirect_uri. Что-то вроде: https://login.microsoftonline.com/00000000-0000-0000-0000-000000000001/oauth2/authorize?client_id=00000000-0000-0000-0000-000000000002&redirect_uri=https%3A%2F%2Foursite3.example.com%3A3443%2Fsignin-oidc&response_type=id_token& scope =openid%20profile&response_mode=form_post& nonce =jkalksdfj alskdjflkjalksdfjalkjA&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0

Однако при входе пользователь получает на сайте следующее:

AADSTS50011: URL-адрес ответа, указанный в запросе, не соответствует URL-адресам ответа, настроенным для приложения: '00000000-0000-0000-0000-000000000003'

Причина этого в том, что URL-адрес ответа приложения AD установлен на:

https://oursite3.example.com/signin-oidc

Однако при ближайшем рассмотрении URL-адрес, на который был перенаправлен пользователь для входа, включает это как redirect_uri:

https://oursite3.example.com:5443/signin-oidc

т.е. порт 5443 был добавлен в конец имени хоста.

По сути, он включает базовый исходный порт в redirect_uri, чего я не ожидал.

Я пробовал использовать ForwardedOptions на нашем сайте. Например, в нашем файле startup.cs содержится следующее (ConfigureServices):

            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                                           ForwardedHeaders.XForwardedProto;
                // Only loopback proxies are allowed by default.
                // Clear that restriction because forwarders are enabled by explicit 
                // configuration.
                options.KnownNetworks.Clear();
                options.KnownProxies.Clear();
            });

а затем (Настроить):

             app.UseForwardedHeaders();

Это не решает проблему.

Я посмотрел, могу ли я переопределить значение, устанавливаемое для redirect_uri, посмотрев здесь: https://github.com/dotnet/aspnetcore/blob/b7e122fbac4207b003dc07f6101e50218be8ff21/src/Security/Authentication/Core/src/AuthenticationHandler.cs

Я также пробовал это: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.1

и это:

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.1

Кто-нибудь знает, что еще может быть не так?

Благодарность

2 ответа

Решение

Мы решили разделить контейнеры на разные экземпляры контейнеров. Обеспечивает простой дизайн.

Когда веб-приложение находится за передней дверцей Azure, нам нужно настроить redirect_uri в запросе /authorize так, чтобы он был адресом передней дверцы.

В приведенном ниже коде мы переопределяем событие «OnRedirectToIdentityProvider» и вставляем адрес входной двери. Когда я пробовал это, я просто жестко закодировал адрес, но в идеале вы должны извлечь его из заголовков, которые Front Door вставляет в запрос.

Это код, который я использовал при попытке аутентифицировать свое серверное приложение Blazor (.net 6), работающее в службе приложений Azure, защищенной Azure AD, работающей за передней дверцей Azure.

      public void ConfigureServices(IServiceCollection services)
{
    // ... existing code

    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
                .EnableTokenAcquisitionToCallDownstreamApi(new[] { "User.Read" })
                .AddInMemoryTokenCaches();

    services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
    {
        options.Events = new OpenIdConnectEvents
        {
            OnRedirectToIdentityProvider = (context) =>
            {   
                // Override the redirect_uri
                //  Ideally extract this from config 
                //  Or context.Request.Headers["X-Forwarded-Host"]
                //  see: https://docs.microsoft.com/en-us/azure/frontdoor/front-door-http-headers-protocol#front-door-to-backend

                context.ProtocolMessage.RedirectUri 
                    = "https://YOUR-FRONT-DOOR-or-APP-GATEWAY/signin-oidc";
                return Task.FromResult(0);
            }
        };
    });

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                        ForwardedHeaders.XForwardedProto;
        options.KnownNetworks.Clear();
        options.KnownProxies.Clear();
    });

    // ... existing code
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ... existing code
    
    // Don't forget to add this ...
    app.UseForwardedHeaders();
    
    // ... existing code
}

Когда код работает, параметр «redirect_uri» должен указывать на вашу переднюю дверь/шлюз, как показано здесь.

Надеюсь, это помогло. ❤️

Другие вопросы по тегам