Skip to content

Add documentation for .NET 10 API endpoint authentication behavior changes #35895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions aspnetcore/fundamentals/minimal-apis/responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -20,6 +22,8 @@ Minimal endpoints support the following types of return values:
1. `T` (Any other type) - This includes `Task<T>` and `ValueTask<T>`.
1. `IResult` based - This includes `Task<IResult>` and `ValueTask<IResult>`.

[!INCLUDE[](~/includes/api-endpoint-auth.md)]

## `string` return values

|Behavior|Content-Type|
Expand Down
2 changes: 2 additions & 0 deletions aspnetcore/includes/api-endpoint-auth.md
Original file line number Diff line number Diff line change
@@ -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 <xref:security/authentication/api-endpoint-auth>.
79 changes: 79 additions & 0 deletions aspnetcore/security/authentication/api-endpoint-auth.md
Original file line number Diff line number Diff line change
@@ -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

- <xref:security/authentication/cookie>
- <xref:web-api/index>
- <xref:fundamentals/minimal-apis/responses>
- <xref:signalr/authn-and-authz>

:::moniker-end
5 changes: 5 additions & 0 deletions aspnetcore/security/authentication/cookie.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `[email protected]` 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 <xref:Microsoft.Extensions.DependencyInjection.AuthenticationServiceCollectionExtensions.AddAuthentication%2A> and <xref:Microsoft.Extensions.DependencyInjection.CookieExtensions.AddCookie%2A> methods.
Expand Down
6 changes: 6 additions & 0 deletions aspnetcore/signalr/authn-and-authz.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions aspnetcore/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions aspnetcore/web-api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <xref:tutorials/min-web-api>.

:::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 <xref:Microsoft.AspNetCore.Mvc.ControllerBase>. The web API project template provides a starter controller:
Expand Down