共用方式為


已知 API 端點的 Cookie 登入重新導向已停用

依預設,對受 Cookie 驗證保護的已知 API 端點發出的未經驗證和未經授權的請求現在會導致 401 和 403 回應,而不是重新導向至登入或拒絕存取的 URI。

已知 API 連接點 是使用新的 IApiEndpointMetadata 介面來識別,而實作新介面的元數據已自動新增至下列專案:

  • [ApiController] 端點。
  • 讀取 JSON 要求內文或寫入 JSON 回應的最小 API 端點。
  • 使用 TypedResults 傳回類型的端點。
  • SignalR 端點。

推出的版本

.NET 10 Preview 7

先前的行為

先前,Cookie 驗證處理程式預設會針對 XMLHttpRequests (XHD) 以外的所有要求,將未經驗證和未經授權的要求重新導向至登入或拒絕存取的 URI。

新行為

從 .NET 10 開始,對已知 API 端點提出未經驗證和未經授權的要求會導致 401 和 403 回應,而不是重新導向至登入或拒絕存取的 URI。 無論目標端點為何,XHR 都會繼續產生 401 和 403 回應。

破壞性變更的類型

此變更為行為變更

變更的原因

這項變更已受到高度要求。 將未經驗證的要求重新導向至登入頁面通常對 API 端點沒有意義,這通常依賴 401 和 403 狀態代碼,而不是 HTML 重新導向來傳達驗證失敗。

如果您想要一律重新導向至未經驗證或未經授權的要求的登入和拒絕存取 URI,不論目標端點為何,或要求的來源是否為 XHR,您可以覆寫 RedirectToLoginRedirectToAccessDenied ,如下所示:

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

如果您想要還原為避免僅重新導向 XHR 的確切先前行為,您可以使用稍微複雜的邏輯來覆寫事件:

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