Cookie Les redirections de connexion sont désactivées pour les points de terminaison d’API connus

Par défaut, les demandes non authentifiées et non autorisées adressées aux points de terminaison d’API connus protégés par cookie l’authentification entraînent désormais des réponses 401 et 403 plutôt que de rediriger vers un URI de connexion ou d’accès refusé.

Les points de terminaison d’API connus sont identifiés à l’aide de la nouvelle IDisableCookieRedirectMetadata interface et les métadonnées implémentant la nouvelle interface ont été ajoutées automatiquement aux éléments suivants :

  • Points de terminaison [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.
  • Points de terminaison SignalR.

L’interface complémentaire IAllowCookieRedirectMetadata choisit un point de terminaison pour rediriger. Il remplace IDisableCookieRedirectMetadata, quel que soit l’ordre dans lequel les métadonnées sont ajoutées.

Les réponses 401 et 403 incluent toujours un Location en-tête contenant l’URI de connexion ou d’accès refusé. Seul le code d’état change.

Seuls les scénarios de challenge (401) et d’interdiction (403) prennent en compte les métadonnées du point de terminaison. Les redirections de déconnexion et d’URL de retour ne sont pas affectées.

Version introduite

.NET 10 Preview 7

Comportement précédent

Auparavant, le cookie gestionnaire d’authentification a redirigé les requêtes non authentifiées et non autorisées vers un URI de connexion ou d’accès refusé par défaut pour toutes les requêtes autres que XMLHttpRequests (XHR).

Nouveau comportement

À compter de .NET 10, les requêtes non authentifiées et non autorisées adressées aux points de terminaison d’API connus entraînent des réponses 401 et 403 plutôt que de rediriger vers un URI de connexion ou d’accès refusé. Les XHR continuent d’entraîner des réponses 401 et 403, quel que soit le point de terminaison cible.

Type de changement cassant

Ce changement est un changement de comportement.

Raison de la modification

Ce changement a été fortement demandé. La redirection de requêtes non authentifiées vers une page de connexion n’est généralement pas logique pour les points de terminaison d’API, qui reposent généralement sur les codes d’état 401 et 403 plutôt que sur les redirections HTML pour communiquer les échecs d’authentification.

Pour restaurer le comportement précédent pour l’ensemble de l’application, activez le Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata commutateur. Cookiel’authentification ignore ensuite les métadonnées de point de terminaison, et seules les XHR entraînent des réponses 401 et 403, qui correspondent au comportement de pré-.NET 10. 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>

Ce commutateur n’est lu qu’une seule fois, la première fois que l’authentification cookie est utilisée. Par conséquent, si vous le définissez plutôt dans le code, appelez SetSwitch avant que l’hôte soit généré :

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

var builder = WebApplication.CreateBuilder(args);

Pour restaurer des redirections pour des points de terminaison individuels à la place, appelez AllowCookieRedirect ou appliquez-la AllowCookieRedirectAttribute à une méthode d’action ou à une classe de contrôleur :

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

À l’inverse, appelez DisableCookieRedirect pour renvoyer les codes d’état 401 et 403 pour les points de terminaison qui ne sont pas détectés automatiquement en tant que points de terminaison d’API.

Si vous souhaitez toujours rediriger vers les URI de connexion et d’accès refusés pour les demandes non authentifiées ou non autorisées, quel que soit le point de terminaison cible ou si la source de la demande est un XHR, vous pouvez remplacer RedirectToLogin et RedirectToAccessDenied comme suit :

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

Si vous souhaitez rétablir le comportement précédent exact qui évite de rediriger uniquement les XHR, vous pouvez remplacer les événements par cette logique légèrement plus complexe :

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

API affectées

Voir aussi