Обрабатывать вход в систему AAD с помощью сайта, перенаправленного из Azure API Management

#azure-active-directory #azure-service-fabric

#azure-active-directory #azure-service-fabric

Вопрос:

У меня есть кластер Service Fabric, в котором запущена служба (без состояния ASP.Net Core), которые не могут быть доступны в Интернете. Запросы к службе маршрутизируются через API Management.

 Incoming request ==> https://blah.trafficmanager.net/routeName
forwarded ==> https://10.0.4.6:[port]/routeName
  

Это отлично работает без аутентификации. Я подключаю авторизацию AAD, поскольку нам нужно заблокировать это до регистрации клиента (из-за требований к запросу прав доступа с привязкой ко времени). Я настроил службу на использование аутентификации AAD, и при запуске в моем локальном кластере службы разработки это работает нормально (т. Е. Запрашивается вход в систему, маршруты стробируются на основе ролей) с использованием этих параметров:

 "AzureAd:ClientId": "[client id]",
"AzureAd:Domain": "[tenant].onmicrosoft.com",
"AzureAd:Instance": "https://login.microsoftonline.com/",
"AzureAd:SignedOutCallbackPath": "/signout-callback-oidc",
"AzureAd:CallbackPath": "/signin-oidc",
"AzureAd:TenantId": "[tenant id]",
  

Когда я развертываю это и пытаюсь нажать на него через https://blah.trafficmanager.net/routeName , перенаправление https://10.0.4.6:44321/signin-oidc , и в итоге я получаю:
введите описание изображения здесь

Вот мой код startup.cs:

 /// <summary>
/// Configure services
/// </summary>
/// <param name="services">Service collection</param>
public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();

    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.Unspecified;

        // Handling SameSite cookie according to https://learn.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
        options.HandleSameSiteCookieCompatibility();
    });

    // Sign-in users with the Microsoft identity platform
    services.AddMicrosoftWebAppAuthentication(this.Configuration);
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.All;

        options.KnownProxies.Add(IPAddress.Parse("10.0.4.6"));
    });

    // services.AddControllers();
    services.AddControllers(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    });
}

/// <summary>
/// Configure app
/// </summary>
/// <param name="app">App builder</param>
/// <param name="env">Environment</param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseDeveloperExceptionPage();

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseForwardedHeaders();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}
  

Мне интересно, могу ли я что-нибудь сделать, чтобы эта служба на узле кластера могла проверять подлинность запросов, поступающих через APIM.

Спасибо!

Комментарии:

1. Я нашел github.com/AzureAD/microsoft-identity-web/issues/115 и если я переопределю reply_uri с помощью контекста. Сообщение протокола. Перенаправляя, я получаю желаемый uri ответа и могу перейти к нему и продолжить проверку подлинности. Я выполняю вход в систему, но выдает ошибку «Мы не смогли вас зарегистрировать» (хотя в диалоговом окне отображается «вход в систему», но, по-видимому, только для MS, а не для клиента, которого я указываю). В приведенной выше ссылке говорится об этом, а позже говорится, что это устарело и использовать перенаправленные заголовки. Это приводит меня к исходной проблеме.

Ответ №1:

Я смог переопределить URL-адрес ответа с помощью этого:

         services.Configure<OpenIdConnectOptions>(
            OpenIdConnectDefaults.AuthenticationScheme,
            options =>
            {
                var redirectToIdpHandler = options.Events.OnRedirectToIdentityProvider;
                options.Events.OnRedirectToIdentityProvider = async context =>
                {
                    // Call what Microsoft.Identity.Web is doing
                    await redirectToIdpHandler(context);

                    // Override the redirect URI so that auth works behind APIM
                    context.ProtocolMessage.RedirectUri = this.Configuration["AzureAd:RedirectUri"];
                };
            });
  

Затем у меня возникли проблемы с авторизацией, поскольку он повторялся много раз и, наконец, выдавал сообщение об ошибке. Я обнаружил, что это связано с тем, что мой URL-адрес ответа был направлен на основной сайт, а не на вход-oidc. Когда я добавил signin-oidc с APIM в качестве URL-адреса ответа, APIM не удался, поскольку не было маршрута с этим именем. Я создал новый API, который перенаправлял signin-oidc на тот же маршрут на серверной части.

Теперь ответ от AAD попадает в мой APIM при входе в систему-oidc и пересылается туда же на обратной стороне. Это позволяет завершить аутентификацию.