diff --git a/aspnetcore/fundamentals/minimal-apis/responses.md b/aspnetcore/fundamentals/minimal-apis/responses.md index 09f826dec11d..286f79481178 100644 --- a/aspnetcore/fundamentals/minimal-apis/responses.md +++ b/aspnetcore/fundamentals/minimal-apis/responses.md @@ -12,6 +12,8 @@ uid: fundamentals/minimal-apis/responses [!INCLUDE[](~/includes/not-latest-version.md)] +This article explains how to create responses for minimal API endpoints in ASP.NET Core. Minimal APIs provide several ways to return data and HTTP status codes. + :::moniker range=">= aspnetcore-10.0" Minimal endpoints support the following types of return values: @@ -20,6 +22,8 @@ Minimal endpoints support the following types of return values: 1. `T` (Any other type) - This includes `Task` and `ValueTask`. 1. `IResult` based - This includes `Task` and `ValueTask`. +[!INCLUDE[](~/includes/api-endpoint-auth.md)] + ## `string` return values |Behavior|Content-Type| diff --git a/aspnetcore/includes/api-endpoint-auth.md b/aspnetcore/includes/api-endpoint-auth.md new file mode 100644 index 000000000000..be7235912c86 --- /dev/null +++ b/aspnetcore/includes/api-endpoint-auth.md @@ -0,0 +1,2 @@ +> [!IMPORTANT] +> Starting with ASP.NET Core 10, known API endpoints no longer redirect to login pages when using cookie authentication. Instead, they return 401/403 status codes. For details, see . \ No newline at end of file diff --git a/aspnetcore/security/authentication/api-endpoint-auth.md b/aspnetcore/security/authentication/api-endpoint-auth.md new file mode 100644 index 000000000000..ba38c46fefc2 --- /dev/null +++ b/aspnetcore/security/authentication/api-endpoint-auth.md @@ -0,0 +1,79 @@ +--- +title: API endpoint authentication behavior in ASP.NET Core +author: wadepickett +description: Learn how ASP.NET Core 10 and later handles authentication failures for API endpoints using cookie authentication. +ai-usage: ai-assisted +monikerRange: '>= aspnetcore-10.0' +ms.author: wpickett +ms.date: 08/06/2025 +uid: security/authentication/api-endpoint-auth +--- + +# API endpoint authentication behavior in ASP.NET Core + +:::moniker range=">= aspnetcore-10.0" + +When using cookie authentication, API endpoints return the appropriate HTTP status codes (such as 401 or 403) for authentication failures instead of redirecting unauthenticated requests to login pages. This behavior, which is more suitable for programmatic API access, was introduced in ASP.NET Core in .NET 10. + +## How ASP.NET Core identifies API endpoints + +ASP.NET Core automatically applies this behavior to endpoints it recognizes as API-related, including: + +- Controllers decorated with the `[ApiController]` attribute +- Minimal API endpoints registered with `MapGet`, `MapPost`, `MapPut`, `MapDelete`, etc. +- Endpoints that explicitly request JSON responses +- SignalR hubs and endpoints + +## Default behavior and customization + +By default, ASP.NET Core applies cookie authentication logic based on the endpoint type: + +- **Web pages**: Redirect to login pages +- **API endpoints**: Return 401 or 403 status codes without redirects + +## Configuring the behavior + +While the default behavior works for most scenarios, it can be customize if needed: + +```csharp +builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) + .AddCookie(options => + { + options.LoginPath = "/Account/Login"; + // The framework automatically handles API endpoints + // No additional configuration needed + }); +``` + +If you need to override the automatic detection for specific endpoints, use the `[Authorize]` attribute with specific authentication schemes or implement custom authentication handlers. + +## Migration considerations + +This change is designed to be non-breaking for existing applications: + +- **Web applications**: Continue to work as before with login page redirects +- **Mixed applications**: API endpoints get proper status codes while web pages get redirects +- **API-only applications**: Benefit from proper HTTP status codes without additional configuration + +### Testing your API endpoints + +After upgrading to ASP.NET Core 10, verify that your API endpoints return appropriate status codes: + +```csharp +[Test] +public async Task UnauthorizedApiRequest_Returns401() +{ + var response = await client.GetAsync("/api/secure-data"); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + Assert.False(response.Headers.Location != null); // No redirect +} +``` + +## Related topics + +- +- +- +- + +:::moniker-end diff --git a/aspnetcore/security/authentication/cookie.md b/aspnetcore/security/authentication/cookie.md index 4914470d6af2..69bf12d04c26 100644 --- a/aspnetcore/security/authentication/cookie.md +++ b/aspnetcore/security/authentication/cookie.md @@ -19,6 +19,11 @@ By [Rick Anderson](https://twitter.com/RickAndMSFT) For demonstration purposes in the sample app, the user account for the hypothetical user, Maria Rodriguez, is hardcoded into the app. Use the **Email** address `maria.rodriguez@contoso.com` and any password to sign in the user. The user is authenticated in the `AuthenticateUser` method in the `Pages/Account/Login.cshtml.cs` file. In a real-world example, the user would be authenticated against a datastore. +:::moniker-end +:::moniker range=">= aspnetcore-10.0" +[!INCLUDE[](~/includes/api-endpoint-auth.md)] +:::moniker-end +:::moniker range=">= aspnetcore-6.0" ## Add cookie authentication * Add the Authentication Middleware services with the and methods. diff --git a/aspnetcore/signalr/authn-and-authz.md b/aspnetcore/signalr/authn-and-authz.md index 9cb9900edf20..c4e1dbe07d97 100644 --- a/aspnetcore/signalr/authn-and-authz.md +++ b/aspnetcore/signalr/authn-and-authz.md @@ -30,6 +30,12 @@ In a browser-based app, cookie authentication allows existing user credentials t Cookies are a browser-specific way to send access tokens, but non-browser clients can send them. When using the [.NET Client](xref:signalr/dotnet-client), the `Cookies` property can be configured in the `.WithUrl` call to provide a cookie. However, using cookie authentication from the .NET client requires the app to provide an API to exchange authentication data for a cookie. +:::moniker-end +:::moniker range=">= aspnetcore-10.0" +[!INCLUDE[](~/includes/api-endpoint-auth.md)] +:::moniker-end +:::moniker range=">= aspnetcore-6.0" + ### Bearer token authentication The client can provide an access token instead of using a cookie. The server validates the token and uses it to identify the user. This validation is done only when the connection is established. During the life of the connection, the server doesn't automatically revalidate to check for token revocation. diff --git a/aspnetcore/toc.yml b/aspnetcore/toc.yml index 41b9da4bc66b..af2802383ae0 100644 --- a/aspnetcore/toc.yml +++ b/aspnetcore/toc.yml @@ -1754,6 +1754,8 @@ items: href: /azure/active-directory-b2c/enable-authentication-web-api - name: Configure cookie authentication uid: security/authentication/cookie + - name: API endpoint authentication behavior + uid: security/authentication/api-endpoint-auth - name: Configure OIDC web authentication uid: security/authentication/configure-oidc-web-authentication - name: Configure JWT bearer authentication diff --git a/aspnetcore/web-api/index.md b/aspnetcore/web-api/index.md index eeeb2b41927f..32fec9fc2165 100644 --- a/aspnetcore/web-api/index.md +++ b/aspnetcore/web-api/index.md @@ -16,6 +16,12 @@ ASP.NET Core supports creating web APIs using controllers or using minimal APIs. This article shows how to use controllers for handling web API requests. For information on creating web APIs without controllers, see . +:::moniker-end +:::moniker range=">= aspnetcore-10.0" +[!INCLUDE[](~/includes/api-endpoint-auth.md)] +:::moniker-end +:::moniker range=">= aspnetcore-7.0" + ## ControllerBase class A controller-based web API consists of one or more controller classes that derive from . The web API project template provides a starter controller: