.NET Core WebAPI защищенная панель управления Hangfire с логином Azure AD

#.net #asp.net-core #asp.net-web-api #azure-active-directory #hangfire

#.net #asp.net-core #asp.net-web-api #azure-active-directory #hangfire

Вопрос:

В настоящее время я пытаюсь обеспечить доступ к панели управления Hangfire.

Поскольку я использую .NET Core WebAPI, я действительно не знаю, как защитить панель управления с помощью Azure AD.

Я пытался использовать политику, но безуспешно:

 services.AddAuthorization(options =>
            {
                // Policy to be applied to hangfire endpoint
                options.AddPolicy(AppConstants.HangfirePoilicyName, builder =>
                {
                    builder
                        .AddAuthenticationSchemes(AzureADDefaults.AuthenticationScheme)
                        .RequireAuthenticatedUser();
                });
            });
 

И здесь метод настройки:

 app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller}/{action=Index}/{id?}")
                    .RequireAuthorization();
                
                endpoints.MapHangfireDashboard("/hangfire", new DashboardOptions()
                    {
                        Authorization = new List<IDashboardAuthorizationFilter> { }
                    })
                    .RequireAuthorization(AppConstants.HangfirePoilicyName);
            });
 

Я ожидаю, что при переходе на панель мониторинга Hangfire я увижу вход в систему Microsoft через Azure AD, а затем войду в свой клиент и получу доступ к панели мониторинга.

Возможно, стоит упомянуть: аутентификация по умолчанию — JWTBearerDefaults, но для панели мониторинга Hangfire мне нужны AzureAdDefaults

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

1. Я застрял на одном и том же, удалось ли вам решить эту проблему?

2. @HashSix Нет, к сожалению, нет

3. @bbrink ты когда-нибудь кончал правильно?

4. @jarodsmk Не совсем

5. @bbrinck На следующей неделе я встречаюсь с некоторыми коллегами — позже опубликую свои выводы 🙂

Ответ №1:

Некоторые предварительные сведения:

  • Решение, которое у меня есть, предназначено для реализаций, которые следуют потокам MSAL 2, используя .NET Core 6.
  • Для заявления:

Аутентификация по умолчанию — JWTBearerDefaults, но для панели мониторинга Hangfire мне нужны AzureAdDefaults

AzureAdDefaults теперь устарел, поэтому вам нужно будет использовать что-то другое, например, JWTBearerDefaults , но читайте дальше, чтобы узнать, как я добился того, чтобы моя реализация работала.

  • Еще одной запутанной вещью для меня было наличие WebAPI, который также действовал как веб-приложение, поскольку вы включаете проверку подлинности, подобную приложению, на определенных конечных точках, а на других — нет. Оказывается, это возможно.

Решение:

Я наткнулся на этот самородок после довольно долгого просмотра примеров кода:

 services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
          .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
              .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
                  .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
                  .AddInMemoryTokenCaches();

services.AddAuthentication()
        .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"),
                                    JwtBearerDefaults.AuthenticationScheme)
        .EnableTokenAcquisitionToCallDownstreamApi();
 

По сути, это означает, что у вас может быть 2 отдельных вызова .AddAuthentication(...) , причем 1 связывает AddMicrosoftIdentityWebApp вызов, а другой AddMicrosoftIdentityWebApi — вызов, указывая, какую аутентификацию использовать в обоих случаях.

Что касается меня, я настраиваю свой Api для аутентификации с JwtBearerDefaults.AuthenticationScheme помощью, и часть веб-приложения использует OpenIdConnectDefaults.AuthenticationScheme , делая его похожим на это:

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"),
                                  JwtBearerDefaults.AuthenticationScheme);

services.AddAuthentication()
            .AddMicrosoftIdentityWebApp(Configuration, "AzureAd", OpenIdConnectDefaults.AuthenticationScheme);
 

Затем настройте политику для использования Hangfire, которая соответствует схеме, ранее настроенной для части веб-приложения.

 services.AddAuthorization(options =>
        {
            options.AddPolicy("azureAdPolicy", builder =>
            {
                builder
                    .AddAuthenticationSchemes(OpenIdConnectDefaults.AuthenticationScheme)
                    .RequireAuthenticatedUser();
            });
        });
 

Затем я создал несколько методов расширения для настройки служб и маршрутов Hangfire.

 public static IServiceCollection AddHangfireService(
        this IServiceCollection services, 
        IConfiguration configuration)
    {
        services.AddHangfireServer();
        services.AddHangfire(cfg =>
        {
            // Additional setup code
        });
        return services;
    }
 

Называется вот так:

  services.AddHangfireService(Configuration);
 

Для маршрутизации:

 public static IEndpointRouteBuilder AddHangfireRoute(this IEndpointRouteBuilder endpoints,
        HangfireDBOptions hangfireDbOptions)
    {
        endpoints.MapHangfireDashboard("/hangfire", new DashboardOptions
        {
            DashboardTitle = "Your App Title",
            AppPath = hangfireDbOptions.BackToSiteUrl,
            Authorization = new[]
            {
                new HangfireDashboardAuthFilter() // if you need a filter
            }
        })
        .RequireAuthorization("azureAdPolicy"); // Matches your policy name
        return endpoints;
    }
 

Который называется примерно так:

 app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers(); // Call this first

            endpoints.AddHangfireRoute(hangfireOptions);
        });
 

Единственное, что осталось сделать, это правильно настроить маршруты для маршрутов Hangfire в среде Azure AD.

При регистрации приложения добавьте тип веб-приложения и добавьте следующие маршруты:

  • (ваш базовый URL-адрес приложения) / вход-oidc
  • (ваш базовый URL-адрес приложения)
  • (ваш базовый URL-адрес приложения) /hangfire

И убедитесь, что установлен флажок ID Token

Скриншот флажка маркера идентификатора Azure AD ID

Так и должно быть 🙂 Надеюсь, это поможет, ваше приложение может использовать другие потоки аутентификации или более старые версии библиотек и т.д. — это то, что я получил, работая, которое в настоящее время используется в производстве. Я бы рекомендовал вам в любом случае обновить свои пакеты, поскольку существует множество «улучшенных» потоков аутентификации, которые можно использовать, и, как я уже упоминал, некоторые функции в настоящее время устарели.

Смиренные извинения еще раз за задержку с ответом, было довольно много информации для компиляции

Ответ №2:

Я думаю, вам не хватает вызова AddAuthentication для AzureAdDefaults:

 services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
        .AddAzureAD(options => Configuration.Bind("AzureAd", options));
 

При этом вызове остальная часть кода должна работать. Как вы упомянули, ваша политика должна быть направлена против AzureAdDefaults, поэтому вам необходимо добавить аутентификацию для схемы.

Где AzureAD — это следующая конфигурация:

 "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "[Enter the domain of your tenant, e.g. contoso.onmicrosoft.com]",
    "TenantId": "[Enter 'common', or 'organizations' or the Tenant Id (Obtained from the Azure portal. Select 'Endpoints' from the 'App registrations' blade and use the GUID in any of the URLs), e.g. da41245a5-11b3-996c-00a8-4d99re19f292]",
    "ClientId": "[Enter the Client Id (Application ID obtained from the Azure portal), e.g. ba74781c2-53c2-442a-97c2-3d60re42f403]"
}
 

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

1. К сожалению, глядя на этот ответ, AzureAdDefaults устарел: (