Укажите пользовательский redirect_uri в веб-приложении, использующем проверку подлинности Azure AD с помощью oidc и промежуточного программного обеспечения

#.net-core #azure-active-directory #openid-connect #service-fabric-stateless

#.net-core #azure-active-directory #OpenID-connect #service-fabric-без состояния

Вопрос:

Я пытаюсь аутентифицировать приложение с помощью Azure AD. В localhost все хорошо, оно перенаправляет на Azure AD, где я ввожу данные для аутентификации, и отправляет обратно токен, позволяющий просматривать ресурс. Все управлялось за кулисами с Microsoft.AspNetCore.Authentication.AzureAD.UI 3.1.10 помощью приложения aspnetcore 3.1.

Мое приложение работает на http://localhost:5000 и я могу настроить redirectUri / replyUri в Azure AD для этого приложения для поддержки этого URL-адреса. Все хорошо.

Проблема заключается в другой среде, когда мое приложение запускается в кластере service fabric. Я вижу проблему

 AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application
  

Когда я проверяю URL-адрес, я вижу, что redirect_uri у него есть такой URL-адрес http://12.12.12.12/signin-oidc

Проблема здесь двойная. Прежде всего, я не знаю, какой IP-адрес будет назначен кластером. Во-вторых, это http, а не https, и он не поддерживается Azure AD.

К счастью, у моего приложения есть внешний URL-адрес с обратным прокси-сервером, который я могу использовать для доступа. Что-то вроде https://myservicefabriccluster.com/MyApp

Этот URL-адрес я мог бы настроить как свой redirect_uri как в своем приложении, так и в Azure AD, но я не знаю, как это сделать.

Мой код имеет что-то вроде этого:

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

где я привязываю свои настройки.

 "AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "ClientId": "76245c66-354e-4a94-b34d-...",
  "TenantId": "59c56bd4-ce18-466a-b515-..."
},
  

Я вижу AzureADOptions , что поддерживает некоторые другие параметры, такие как Domain (не требуется) или CallbackPath (что по умолчанию нормально /signin-oidc ), но нет ничего похожего на ReplyUrl или redirectUri, где я могу указать абсолютный URL-адрес в качестве обратного вызова.

Я нашел несколько похожих проблем без ответа. Другие предлагают некоторые хитрости, такие как промежуточное программное обеспечение, которое перезаписывает этот параметр непосредственно перед перенаправлением в Azure AD.

Конечно, должен быть более простой способ решения этой проблемы, который, я ожидаю, не такой уж странный. Пожалуйста, помогите?

Ответ №1:

Решение перезаписать redirect_uri параметр пользовательским значением — использовать события, доступные в библиотеке OpenIdConnect. Эта библиотека должна быть доступна, поскольку она зависит от Microsoft.AspNetCore.Authentication.AzureAD.UI , поэтому это мое решение, которое в дополнение к стандартным свойствам для AzureADOptions добавляет флаг, определяющий, нужно ли перезаписывать uri перенаправления, и значение для этого. Я надеюсь, что это самоочевидно

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

var isCustomRedirectUriRequired = configuration.GetValue<bool>("AzureAd:IsCustomRedirectUriRequired");
if (isCustomRedirectUriRequired)
{
    services
        .Configure<OpenIdConnectOptions>(
            AzureADDefaults.OpenIdScheme,
            options =>
            {
                options.Events =
                    new OpenIdConnectEvents
                    {
                        OnRedirectToIdentityProvider = async ctx =>
                        {
                            ctx.ProtocolMessage.RedirectUri =
                                configuration.GetValue<string>("AzureAd:CustomRedirectUri");
                            await Task.Yield();
                        }
                    };
            });
}

services
    .AddAuthorization(
        options =>
        {
            options.AddPolicy(
                PolicyConstants.DashboardPolicy,
                builder =>
                {
                    builder
                        .AddAuthenticationSchemes(AzureADDefaults.AuthenticationScheme)
                        .RequireAuthenticatedUser();
                });
        });
  

И appsettings.json у этого будет что-то вроде этого:

 "AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "ClientId": "76245c66-354e-4a94-b34d-...",
  "TenantId": "59c56bd4-ce18-466a-b515-..."
  "IsCustomRedirectUriRequired": true,
  "CustomRedirectUri": "https://platform-cluster-development01.cubictelecom.com:19008/Scheduler/WebApi/signin-oidc"
},
  

Обратите IsCustomRedirectUriRequired внимание, что и CustomRedirectUri — это мои пользовательские свойства, которые я явно читаю, чтобы перезаписать (или нет) параметр запроса uri перенаправления при перенаправлении к поставщику удостоверений (т. Е. Azure AD)

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

1. Я попробовал тот же подход, Microsoft.Identity.Web и он работает таким же образом.

Ответ №2:

Учитывая это, вы должны настроить общедоступный URL-адрес в качестве URI перенаправления, который имеет значение, подобное этому:

Похоже, что вышеупомянутая библиотека с трудом поддерживает это и заставляет URI перенаправления основываться на URL-адресе HTTP для прослушивания кода. В рамках решения этой проблемы стоит подумать о том, как вы пишете свой код:

Эта строка кода указывает, что ваше приложение может работать только с Azure AD:

 - services.AddAzureAD
  

Эта строка кода гарантирует, что ваш код будет работать как с AzureAD, так и с любым другим сервером авторизации, который соответствует стандарту Open Id Connect:

 - services.AddOpenIdConnect
  

Последний параметр также содержит класс Events с обычно используемой операцией OnRedirectToIdentityProvider, которую можно использовать для переопределения пути обратного вызова и предоставления полного перенаправления.

Конечные точки Azure AD основаны на стандартах, поэтому вам не обязательно использовать библиотеки, специфичные для AzureAD. Из интереса у меня есть одностраничный пример кода Azure для приложений, который использует нейтральную библиотеку, подобную этой, поэтому я знаю, что этот метод работает.

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

1. Спасибо, вы указали мне правильное направление. Однако библиотека не устарела. На самом деле есть новая версия для .NET 5.0, но вы правы, эта библиотека немного ограничена, и я все еще могу использовать более стандартную библиотеку OpenIdConnect для доступа к событиям. Я скоро опубликую решение