Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Ao utilizar cookie autenticação, os endpoints da API devolvem os códigos de estado HTTP apropriados (401 ou 403) para falhas de autenticação, em vez de redirecionarem pedidos não autenticados para as páginas de login. Esse comportamento, que é mais adequado para acesso à API programática, foi introduzido no ASP.NET Core no .NET 10.
Como o ASP.NET Core identifica os endpoints da API
O ASP.NET Core adiciona IDisableCookieRedirectMetadata aos endpoints que reconhece como endpoints da API, incluindo:
- Controladores decorados com o atributo
[ApiController]. - Endpoints mínimos de API que leiam corpos de pedidos JSON ou escrevam respostas JSON.
- Endpoints usando TypedResults tipos de retorno.
- SignalR hubs e pontos finais.
A deteção baseia-se em metadados que são inferidos quando a aplicação constrói os seus endpoints. Não se baseia no Accept cabeçalho de um pedido recebido, nem no Map{Verb} método que registou a rota.
Um processador minimalista de API cujo tipo de retorno declarado seja void, string ou a interface IResult não contribui para os metadados através do respetivo tipo de retorno, ao contrário dos tipos concretos TypedResults, como Ok<TValue>, que o fazem. Por exemplo, app.MapGet("/hello", () => "Hello").RequireAuthorization() escreve uma text/plain resposta e não aceita o corpo do pedido JSON, por isso pedidos não autenticados continuam a redirecionar para a página de login.
Comportamento padrão
Por predefinição, o ASP.NET Core aplica a lógica de autenticação cookie consoante o tipo de endpoint:
- Páginas web: Redirecionar para a página de login ou acesso negado com um código de estado 302.
- Endpoints da API: Devolver códigos de estado 401 ou 403 em vez de um redirecionamento 302.
Os XMLHttpRequests (XHRs) recebem respostas 401 e 403 independentemente do endpoint que visam. Esse comportamento é anterior ao .NET 10 e mantém-se inalterado.
Note
Os metadados dos endpoints afetam apenas os caminhos de desafio (401) e proibição (403). Os redirecionamentos ao terminar sessão não são afetados. Quando um pedido de terminação de sessão especifica um URI de redirecionamento ou um URL de retorno válido, os pedidos que não são XHR são redirecionados tal como acontecia antes do .NET 10. O comportamento na XHR mantém-se inalterado.
Configure o comportamento para endpoints específicos
Chamada DisableCookieRedirect para devolver códigos de estado 401 e 403 para endpoints que não são detetados automaticamente:
var api = app.MapGroup("/api").DisableCookieRedirect();
api.MapGet("/status", () => "Ready")
.RequireAuthorization();
Chame AllowCookieRedirect para manter os redirecionamentos de início de sessão para pontos finais que são detetados como pontos finais da API:
app.MapGet("/reports/summary", () => new { Total = 1000 })
.RequireAuthorization()
.AllowCookieRedirect();
Para comandos, aplique o AllowCookieRedirectAttribute a um método de ação ou à classe controladora:
[ApiController]
[Authorize]
[AllowCookieRedirect]
[Route("[controller]")]
public class ReportsController : ControllerBase
{
[HttpGet("summary")]
public object GetSummary() => new { Total = 1000 };
}
Importante
IAllowCookieRedirectMetadata sobrepõe-se IDisableCookieRedirectMetadata independentemente da ordem em que os metadados são adicionados. Chamar DisableCookieRedirect depois de AllowCookieRedirect no mesmo endpoint não restaura o comportamento do código de estado.
Desativar este comportamento em toda a aplicação
Para restaurar o comportamento anterior ao .NET 10 em toda a aplicação, ative a opção Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata. Quando está ativada, cookie a autenticação ignora os metadados do endpoint e apenas os XHRs resultam em respostas 401 e 403.
Defina o switch no ficheiro do projeto para que se aplique antes de qualquer código da aplicação ser executado:
<ItemGroup>
<RuntimeHostConfigurationOption
Include="Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata"
Value="true" />
</ItemGroup>
O interruptor também pode ser definido em código. Só é lido uma vez, da primeira vez que a autenticação cookie é utilizada, por isso chama SetSwitch antes de o anfitrião ser criado:
AppContext.SetSwitch(
"Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata", true);
var builder = WebApplication.CreateBuilder(args);
Considerações sobre mudanças de última hora
A alteração introduzida no .NET 10 é uma alteração comportamental. Uma aplicação que combina a autenticação cookie com endpoints que o ASP.NET Core deteta como endpoints de API passa a devolver respostas 401 e 403 nos casos em que anteriormente devolvia um redirecionamento 302 para a página de início de sessão ou para a página de acesso negado. Para obter o aviso completo sobre a alteração interruptiva, consulte Cookie os redirecionamentos de início de sessão estão desativados para endpoints conhecidos da API.
Considere o impacto em cada tipo de aplicação:
- Aplicações web: Os pontos finais das páginas continuam a redirecionar para a página de início de sessão.
- Aplicações mistas: os endpoints da API devolvem códigos de estado enquanto as páginas web recebem redirecionamentos, pelo que o código do navegador que se seguiu ao redirecionamento tem de gerir os 401 e 403 em vez disso.
- Aplicações exclusivamente de API: Os pontos de extremidade da API detetados devolvem códigos de estado HTTP corretos sem configuração adicional.
Para manter o comportamento anterior, ligue AllowCookieRedirect aos endpoints afetados, aplique [AllowCookieRedirect] aos controladores afetados ou ative o Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata switch para toda a aplicação.
Testar os endpoints da sua API
Após atualizar para ASP.NET Core no .NET 10, verifique se os endpoints da sua API retornam os códigos de estado apropriados:
[Fact]
public async Task UnauthorizedApiRequest_Returns401()
{
var response = await client.GetAsync("/api/secure-data");
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
// The handler sets the Location header before setting the status code,
// so the login URI is still present on the 401 response.
Assert.NotNull(response.Headers.Location);
}