Microsoft Identity Web: изменить URI перенаправления
Я использую .net 5, Identity Web Ui для доступа к Microsoft Graph. Где я могу настроить свой URI перенаправления?
Мне нужно указать полный Uri, поскольку сгенерированный из callbackUri неверен из-за того, что он находится за балансировщиком нагрузки с разгрузкой SSL.
Вот мой текущий раздел ConfigureServices
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
3 ответа
Я столкнулся с аналогичной проблемой с WebApp, доступным только за входной дверью, WebApp должен был вызывать настраиваемый нисходящий WebApi.
Моя конфигурация службы, которая работала на моей машине разработчика localhost:
// AzureAdB2C
services
.AddMicrosoftIdentityWebAppAuthentication(
Configuration,
"AzureAdB2C", subscribeToOpenIdConnectMiddlewareDiagnosticsEvents: true)
.EnableTokenAcquisitionToCallDownstreamApi(p =>
{
p.RedirectUri = redUri; // NOT WORKING, WHY?
p.EnablePiiLogging = true;
},
[... an array with my needed scopes]
)
.AddInMemoryTokenCaches();
Я попробовал AddDownstreamWebApi, но мне не удалось заставить его работать, поэтому я просто получил необходимый токен с помощью ITokenAcquisition и добавил его в HttpClient, чтобы сделать свой запрос.
Затем мне потребовалось перенаправление входа в AzureAd / B2C на uri с URL-адресом входной двери: https://example.org/signin-oidc, и все сломалось. Я решил это так:
Прежде всего, вы должны добавить этот URL-адрес в свою регистрацию приложения на лазурном портале, очень важно учитывать регистр, он заботится о конечных косых чертах, и я подозреваю, что многие URL-адреса указывают на один и тот же контроллер, и их порядок имеет некоторое влияние, Я просто удалил все и сохранил минимум.
Затем в методе настройки служб:
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SaveTokens = true; // this saves the token for the downstream api
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = async ctxt =>
{
// Invoked before redirecting to the identity provider to authenticate. This can be used to set ProtocolMessage.State
// that will be persisted through the authentication process. The ProtocolMessage can also be used to add or customize
// parameters sent to the identity provider.
ctxt.ProtocolMessage.RedirectUri = "https://example.org/signin-oidc";
await Task.Yield();
}
};
});
При этом перенаправление сработало, но я вошел в цикл между защищенной страницей и логином AzureB2C.
После успешного входа в систему и правильного перенаправления на контроллер signin-oidc (созданный пакетом Identity.Web) я снова был правильно перенаправлен на страницу, с которой началась вся эта авторизация, но там авторизация не нашла. Итак, я добавил / модифицировал также это:
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.None;
options.Secure = CookieSecurePolicy.Always;
});
При этом авторизация сработала, но я не смог получить токен для вызова нижележащего API, до того, как эта вещь перенаправления ITokenAcquisition работала, но теперь при попытке получить токен он выдает исключение.
Итак, в моем контроллере / службе, чтобы получить токен, который я изменил и использовал:
var accessToken = await _contextAccessor.HttpContext
.GetTokenAsync(OpenIdConnectDefaults.AuthenticationScheme, "access_token");
Итак, теперь с токеном я добавляю его в свой HttpRequestMessage следующим образом:
request.Headers.Add("Authorization", $"Bearer {accessToken}");
Я жил на StackOverflow и microsoft docs в течение 3 дней, я не уверен, что все это «рекомендуется», но у меня это сработало.
У меня была такая же проблема с запуском приложения asp.net в Google Cloud Run, которое прерывает соединение TLS. Я получал сообщение об ошибке:AADSTS50011: URL-адрес ответа, указанный в запросе, не соответствует URL-адресам ответа, настроенным для приложения.
Используя fiddler, я изучил запрос на login.microsoftonline.com и обнаружил, что параметр запроса redirect_uri точно соответствует URL-адресу, который я настроил в приложении в Azure, за исключением того, что он начинался с http, а не с https.
Сначала я пробовал другие ответы, связанные с обработкой события OpenIdConnectEvents и обновлением URI перенаправления. Это зафиксировало параметр redirect_url в вызове login.microsoftonline.com, и затем он работал, пока я не добавил в граф API. Затем я обнаружил, что страница signin-oidc моего сайта выдает собственную ошибку о несоответствии URI перенаправления. Затем это приведет к тому, что он попадет в цикл между моим сайтом и login.microsoftonline.com, неоднократно пытаясь аутентифицироваться, пока в конечном итоге я не получу ошибку входа.
В ходе дальнейших исследований ASP.net предоставляет промежуточное программное обеспечение для правильной обработки этого сценария. Ваш балансировщик нагрузки SSL должен добавить в запрос стандартный заголовок X-Forwarded-Proto со значением HTTPS. Он также должен отправить заголовок X-Forwarded-For с исходным IP-адресом, который может быть полезен для отладки, определения географического IP-адреса и т. д.
В приложении ASP.net для настройки промежуточного программного обеспечения:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
Затем включите промежуточное ПО:
app.UseForwardedHeaders();
Важно отметить, что вы должны включить это перед вызовами app.UseAuthentication/app.UseAuthorization, которые зависят от него.
Если ваш балансировщик нагрузки не добавляет заголовок X-Forwarded-Proto и не может быть настроен для этого, в приведенном выше документе описаны другие варианты.
Я столкнулся с подобной проблемой в течение 3 дней. Приведенный ниже код помог мне решить проблему.
string[] initialScopes = Configuration.GetValue<string>("CallApi:ScopeForAccessToken")?.Split(' ');
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddInMemoryTokenCaches();
services.AddControllers();
services.AddRazorPages().AddMvcOptions(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SaveTokens = true; // this saves the token for the downstream api
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = async ctxt =>
{
ctxt.ProtocolMessage.RedirectUri = "https://example.org/signin-oidc";
await Task.Yield();
}
};
});