Отключить AutomaticChallenge в ядре asp.net mvc 2 OpenIdConnect

Я добавил аутентификацию OpenID в свое веб-приложение ASP.NET Core 2.0:

services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
            .AddCookie()
            .AddOpenIdConnect(option =>
            {
                option.ClientId = Configuration["AzureAD:ClientId"];
                option.Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAd:Tenant"]);
                option.SignedOutRedirectUri = Configuration["AzureAd:PostLogoutRedirectUri"];
            });

Как включить автоматический вызов, чтобы контроллер, соответствующее действие с AuthorizeAttribute возвращало 403, а не перенаправляло?

EDIT: я закончил с этим:

.AddOpenIdConnect(option =>
{
    ...
    option.Events = new OpenIdConnectEvents
    {
        OnRedirectToIdentityProvider = context =>
        {
            bool isAjaxRequest = context.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
            if (isAjaxRequest)
            {
                context.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
                //context.HttpContext.Response.Headers["Location"] = ???request.RedirectUrl;
                context.HandleResponse();
            }
            return Task.CompletedTask;
        }
    };
});

Хотя я не хочу перенаправлять запрос Ajax (почему?), я хотел бы передать URL-адрес перенаправления клиенту. Как получить RedirectURL?


person Liero    schedule 14.09.2017    source источник
comment
В StackOverflow уже есть решение этой проблемы: stackoverflow.com/questions/45878166/   -  person Raphael Müllner    schedule 15.09.2017
comment
В моем случае это немного отличается, так как я использую OpenIdConnect, и предлагаемый OnRedirectToLogin никогда не срабатывает. Однако в OpenIdOptions есть OnRedirectToIdentityProvider.   -  person Liero    schedule 18.09.2017
comment
Вы пробовали варианты аутентификации cookie из решения в другом потоке? Насколько мне известно, перенаправления всегда выполняются с помощью проверки подлинности файлов cookie.   -  person Raphael Müllner    schedule 18.09.2017
comment
Да, событие проверки подлинности файлов cookie не произошло   -  person Liero    schedule 18.09.2017
comment
Извините, просмотрел эту часть вашего комментария. Что, если вы реализуете ту же логику для события OnRedirectToIdentityProvider?   -  person Raphael Müllner    schedule 18.09.2017
comment
Я сделал, и это работает, однако я не могу поймать URI перенаправления. Это все, и было бы удобно, если бы я мог   -  person Liero    schedule 18.09.2017
comment
Удалите DefaultChallengeScheme, если вы хотите, чтобы аутентификация cookie обрабатывала вызов, в него встроена эта логика ajax.   -  person Tratcher    schedule 18.09.2017
comment
@Tratcher: но если я удалю его, неаутентифицированный запрос без ajax не будет перенаправлен поставщику удостоверений, не так ли?   -  person Liero    schedule 01.02.2018
comment
Имея ту же проблему, прямо сейчас я позволяю запросу Ajax обрабатывать код ответа 401 и выполнять перенаправление. Но я хотел бы более прямое решение, которому не нужно ждать запроса ajax.   -  person Robban1980    schedule 05.07.2018


Ответы (1)


Лучшее решение, которое я смог найти до сих пор, это:

services.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
  .AddCookie(options =>
  {
      options.Events.OnRedirectToAccessDenied = DontRedirectAjaxOrApiRequestToForbidden;
  })
  .AddOpenIdConnect(options =>
  {
      ...
      options.Events.OnRedirectToIdentityProvider = DontRedirectAjaxRequestToOpenIdProvider;
  });


/// <summary>
/// Unauthenticated ajax or API request returns 403 rather than Redirect to forbidden page
/// </summary>
private static Task DontRedirectAjaxOrApiRequestToForbidden(RedirectContext<CookieAuthenticationOptions> ctx)
{
    bool isAjaxRequest = ctx.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
    if (isAjaxRequest || (ctx.Request.Path.StartsWithSegments("/api")))
    {
        ctx.Response.StatusCode = 403;
    }
    else
    {
        ctx.Response.Redirect(ctx.RedirectUri);
    }
    return Task.CompletedTask;
}

/// <summary>
/// Unauthenticated ajax request returns 401 rather than Redirect
/// </summary>
private static Task DontRedirectAjaxRequestToOpenIdProvider(RedirectContext redirectContext)
{
    bool isAjaxRequest = redirectContext.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
    if (isAjaxRequest)
    {
        redirectContext.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
        redirectContext.HttpContext.Response.Headers["Location"] = CookieAuthenticationDefaults.LoginPath.Value;
        redirectContext.HandleResponse();
    }
    return Task.CompletedTask;
}
person Liero    schedule 05.07.2018