Cookie Os redirecionamentos de logon estão desabilitados para endpoints de API conhecidos

Por padrão, as solicitações não autenticadas e não autorizadas feitas a pontos de extremidade de API conhecidos protegidos pela autenticação cookie agora resultam em respostas 401 e 403, em vez de redirecionamento para um URI de login ou acesso negado.

Os endpoints de API conhecidos são identificados usando a nova interface IDisableCookieRedirectMetadata, e os metadados que implementam a nova interface foram adicionados automaticamente aos itens a seguir:

  • Pontos de extremidade [ApiController].
  • Pontos de extremidade de API mínimos que processam corpos de solicitação JSON ou geram respostas JSON.
  • Os pontos de extremidade que utilizam tipos de retorno TypedResults.
  • Pontos de extremidade SignalR.

A interface complementar IAllowCookieRedirectMetadata inclui novamente um endpoint nos redirecionamentos. Ela substitui IDisableCookieRedirectMetadata não importa a ordem na qual os metadados são adicionados.

As respostas 401 e 403 ainda incluem um cabeçalho Location que contém o URI de login ou de acesso negado. Somente o código de status é alterado.

Somente os fluxos de desafio (401) e de negação de acesso (403) levam em consideração os metadados do endpoint. Os redirecionamentos de logout e para URL de retorno não são afetados.

Versão introduzida

.NET 10 Versão Prévia 7

Comportamento anterior

Anteriormente, o cookie manipulador de autenticação redirecionava solicitações não autenticadas e não autorizadas para um URI de login ou de acesso negado por padrão para todas as solicitações exceto XHRs (XMLHttpRequests).

Novo comportamento

A partir do .NET 10, solicitações não autenticadas e não autorizadas feitas a endpoints de API conhecidos resultam em respostas 401 e 403, em vez de redirecionar para um login ou URI de acesso negado. Os XHRs continuam a resultar em respostas 401 e 403, independentemente do ponto de extremidade de destino.

Tipo de mudança disruptiva

Essa alteração é uma mudança comportamental.

Motivo da alteração

Essa alteração foi altamente solicitada. Redirecionar solicitações não autenticadas para uma página de logon geralmente não faz sentido para pontos de extremidade de API, que normalmente dependem de códigos de status 401 e 403 em vez de redirecionamentos HTML para comunicar falhas de autenticação.

Para restaurar o comportamento anterior de todo o aplicativo, habilite a opção Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata . CookieA autenticação ignora os metadados do ponto de extremidade e apenas os XHRs resultam em respostas 401 e 403, que correspondem ao comportamento pré-.NET 10. Defina a opção no arquivo de projeto para que ela se aplique antes que qualquer código de aplicativo seja executado:

<ItemGroup>
  <RuntimeHostConfigurationOption
    Include="Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata"
    Value="true" />
</ItemGroup>

A chave é lida uma vez, quando a autenticação é usada pela primeira vez cookie, portanto, se você definir a chave no código, chame SetSwitch antes de o host ser criado:

AppContext.SetSwitch(
    "Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata", true);

var builder = WebApplication.CreateBuilder(args);

Para restaurar redirecionamentos para endpoints individuais, chame AllowCookieRedirect ou aplique AllowCookieRedirectAttribute a um método de ação ou à classe do controlador:

app.MapGet("/reports/summary", () => new { Total = 1000 })
   .RequireAuthorization()
   .AllowCookieRedirect();

Por outro lado, chame DisableCookieRedirect para retornar códigos de status 401 e 403 para endpoints que não são detectados automaticamente como endpoints de API.

Se você quiser sempre redirecionar para os URIs de login e de acesso negado para solicitações não autenticadas ou não autorizadas, independentemente do ponto de extremidade de destino ou se a origem da solicitação é um XHR, você pode sobrescrever RedirectToLogin e RedirectToAccessDenied da seguinte maneira:

builder.Services.AddAuthentication()
    .AddCookie(options =>
    {
        options.Events.OnRedirectToLogin = context =>
        {
            context.Response.Redirect(context.RedirectUri);
            return Task.CompletedTask;
        };

        options.Events.OnRedirectToAccessDenied = context =>
        {
            context.Response.Redirect(context.RedirectUri);
            return Task.CompletedTask;
        };
    });

Se você quiser reverter para o comportamento anterior exato que evita o redirecionamento apenas para XHRs, você poderá substituir os eventos com essa lógica um pouco mais complicada:

builder.Services.AddAuthentication()
    .AddCookie(options =>
    {
        bool IsXhr(HttpRequest request)
        {
            return string.Equals(request.Query[HeaderNames.XRequestedWith], "XMLHttpRequest", StringComparison.Ordinal) ||
                string.Equals(request.Headers.XRequestedWith, "XMLHttpRequest", StringComparison.Ordinal);
        }

        options.Events.OnRedirectToLogin = context =>
        {
            if (IsXhr(context.Request))
            {
                context.Response.Headers.Location = context.RedirectUri;
                context.Response.StatusCode = 401;
            }
            else
            {
                context.Response.Redirect(context.RedirectUri);
            }

            return Task.CompletedTask;
        };

        options.Events.OnRedirectToAccessDenied = context =>
        {
            if (IsXhr(context.Request))
            {
                context.Response.Headers.Location = context.RedirectUri;
                context.Response.StatusCode = 403;
            }
            else
            {
                context.Response.Redirect(context.RedirectUri);
            }

            return Task.CompletedTask;
        };
    });

APIs afetadas

Consulte também