Comportement d’authentification du point de terminaison d’API dans ASP.NET Core

Lorsque vous utilisez cookie l’authentification, les points de terminaison d’API retournent les codes d’état HTTP appropriés (401 ou 403) pour les échecs d’authentification au lieu de rediriger les demandes non authentifiées vers les pages de connexion. Ce comportement, plus adapté à l’accès par programmation aux API, a été introduit dans ASP.NET Core dans .NET 10.

Comment ASP.NET Core identifie les points de terminaison d’API

ASP.NET Core ajoute IDisableCookieRedirectMetadata aux points de terminaison qu’il reconnaît comme points de terminaison d’API, notamment :

  • Contrôleurs décorés avec l’attribut [ApiController] .
  • Points de terminaison d’API minimaux qui lisent les corps de requêtes JSON ou écrivent des réponses JSON.
  • Points de terminaison utilisant des types de retour TypedResults.
  • SignalR hubs et points de terminaison.

La détection est basée sur les métadonnées déduites lorsque l’application génère ses points de terminaison. Elle n’est pas basée sur l’en-tête Accept d’une requête entrante, et elle n’est pas basée sur la méthode qui Map{Verb} a inscrit l’itinéraire.

Un gestionnaire d’API minimal dont le type de retour déclaré est void, string ou l’interface IResult n’apporte pas de métadonnées via son type de retour, alors que les types concrets TypedResults, tels que Ok<TValue>, le font. Par exemple, text/plain renvoie une réponse app.MapGet("/hello", () => "Hello").RequireAuthorization() et n’accepte pas de corps de requête JSON. Ainsi, les requêtes non authentifiées qui lui sont envoyées sont toujours redirigées vers la page de connexion.

Comportement par défaut

Par défaut, ASP.NET Core applique cookie la logique d’authentification en fonction du type de point de terminaison :

  • Pages web : redirigez vers la page de connexion ou d’accès refusée avec un code d’état 302.
  • Points de terminaison d’API : retournez les codes d’état 401 ou 403 au lieu d’une redirection 302.

XMLHttpRequests (XHR) reçoit 401 et 403 réponses, quel que soit le point de terminaison qu’ils ciblent. Ce comportement précède .NET 10 et n’est pas modifié.

Note

Les métadonnées du point de terminaison n’affectent que les chemins de réponse de demande d’authentification (401) et de refus d’accès (403). Les redirections de déconnexion ne sont pas affectées. Lorsqu’une demande de déconnexion spécifie un URI de redirection ou une URL de retour valide, les demandes non XHR sont redirigées comme elles l’ont fait avant .NET 10. Le comportement XHR n’est pas modifié.

Configurer le comportement pour des points de terminaison spécifiques

Appelez DisableCookieRedirect pour retourner les codes d’état 401 et 403 pour les points de terminaison qui ne sont pas détectés automatiquement :

var api = app.MapGroup("/api").DisableCookieRedirect();

api.MapGet("/status", () => "Ready")
   .RequireAuthorization();

Appelez AllowCookieRedirect pour conserver les redirections de connexion pour les points de terminaison détectés en tant que points de terminaison d’API :

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

Pour les contrôleurs, appliquez AllowCookieRedirectAttribute à une méthode d’action ou à la classe du contrôleur :

[ApiController]
[Authorize]
[AllowCookieRedirect]
[Route("[controller]")]
public class ReportsController : ControllerBase
{
    [HttpGet("summary")]
    public object GetSummary() => new { Total = 1000 };
}

Important

IAllowCookieRedirectMetadata remplace l’ordre dans lequel les métadonnées sont ajoutées IDisableCookieRedirectMetadata . L’appel DisableCookieRedirect après AllowCookieRedirect sur le même point de terminaison ne restaure pas le comportement du code d’état.

Désactiver cette fonctionnalité pour toute l’application

Pour restaurer le comportement de pré-.NET 10 pour une application entière, activez le Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata commutateur. Quand elle est activée, cookie l’authentification ignore les métadonnées de point de terminaison et uniquement les XHR entraînent des réponses 401 et 403.

Définissez le commutateur dans le fichier projet afin qu’il s’applique avant l’exécution d’un code d’application :

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

Le commutateur peut également être défini dans le code. Il n’est lu qu’une seule fois, la première fois que l’authentification cookie est utilisée, donc appelez SetSwitch avant la création de l’hôte :

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

var builder = WebApplication.CreateBuilder(args);

Considérations sur les changements cassants

Le changement introduit dans .NET 10 est un changement comportemental. Une application qui combine l’authentification cookie avec des points de terminaison qu’ASP.NET Core détecte comme des points de terminaison d’API renvoie des réponses 401 et 403, alors qu’elle renvoyait auparavant une redirection 302 vers la page de connexion ou de refus d’accès. Pour consulter l’avis complet concernant ce changement avec rupture, voir la Cookie désactivation des redirections de connexion pour les points de terminaison d’API connus.

Tenez compte de l’impact sur chaque type d’application :

  • Applications web : les points de terminaison de page continuent de rediriger vers la page de connexion.
  • Applications mixtes : les points de terminaison d’API retournent des codes d’état pendant que les pages web reçoivent des redirections. Par conséquent, le code du navigateur qui a suivi la redirection doit gérer 401 et 403 à la place.
  • Applications API uniquement : les points de terminaison d’API détectés retournent des codes d’état HTTP appropriés sans configuration supplémentaire.

Pour conserver le comportement précédent, appelez AllowCookieRedirect sur les points de terminaison concernés, appliquez [AllowCookieRedirect] aux contrôleurs concernés ou activez l’option Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata pour l’ensemble de l’application.

Test de vos points de terminaison d’API

Après la mise à niveau vers ASP.NET Core dans .NET 10, vérifiez que vos points de terminaison d’API retournent les codes d’état appropriés :

[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);
}