Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Quando si usa cookie l'autenticazione, gli endpoint API restituiscono i codici di stato HTTP appropriati (401 o 403) per gli errori di autenticazione anziché reindirizzare le richieste non autenticate alle pagine di accesso. Questo comportamento, più adatto per l'accesso all'API a livello di codice, è stato introdotto in ASP.NET Core in .NET 10.
Come ASP.NET Core identifica gli endpoint API
ASP.NET Core aggiunge IDisableCookieRedirectMetadata agli endpoint riconosciuti come endpoint API, tra cui:
- Controller contrassegnati con l'attributo
[ApiController]. - Endpoint API minimi che leggono i corpi delle richieste JSON o scrivono risposte JSON.
- Endpoint che usano TypedResults tipi di ritorno.
- SignalR hub e dispositivi finali.
Il rilevamento si basa sui metadati dedotti quando l'app compila gli endpoint. Non si basa sull'header Accept di una richiesta in entrata e non si basa su quale metodo Map{Verb} ha registrato il percorso.
Un handler di API minime il cui tipo restituito dichiarato è void, string o l'interfaccia IResult non contribuisce ai metadati attraverso il proprio tipo restituito, mentre invece i tipi concreti TypedResults, come Ok<TValue>, lo fanno. Ad esempio, app.MapGet("/hello", () => "Hello").RequireAuthorization() scrive una text/plain risposta e non accetta il corpo della richiesta JSON, quindi le richieste non autenticate vengono comunque reindirizzate alla pagina di accesso.
Comportamento predefinito
Per impostazione predefinita, ASP.NET Core applica cookie la logica di autenticazione in base al tipo di endpoint:
- Pagine Web: reindirizzare alla pagina di accesso o accesso negato con un codice di stato 302.
- Endpoint API: restituisce codici di stato 401 o 403 anziché un reindirizzamento 302.
XMLHttpRequests (XHRs) riceve risposte 401 e 403 indipendentemente dall'endpoint di destinazione. Questo comportamento precede .NET 10 e rimane invariato.
Annotazioni
I metadati dell'endpoint influiscono solo sui percorsi di challenge (401) e forbid (403). I reindirizzamenti di disconnessione non subiscono modifiche. Quando una richiesta di disconnessione specifica un URI di reindirizzamento o un URL di ritorno valido, le richieste non XHR vengono reindirizzate come avveniva prima di .NET 10. Il comportamento XHR rimane invariato.
Configurare il comportamento per endpoint specifici
Chiamare DisableCookieRedirect per restituire i codici di stato 401 e 403 per gli endpoint che non vengono rilevati automaticamente:
var api = app.MapGroup("/api").DisableCookieRedirect();
api.MapGet("/status", () => "Ready")
.RequireAuthorization();
Chiamare AllowCookieRedirect per mantenere i reindirizzamenti di accesso per gli endpoint rilevati come endpoint API:
app.MapGet("/reports/summary", () => new { Total = 1000 })
.RequireAuthorization()
.AllowCookieRedirect();
Per i controller, applicare AllowCookieRedirectAttribute a un metodo di azione o alla classe del controller:
[ApiController]
[Authorize]
[AllowCookieRedirect]
[Route("[controller]")]
public class ReportsController : ControllerBase
{
[HttpGet("summary")]
public object GetSummary() => new { Total = 1000 };
}
Importante
IAllowCookieRedirectMetadata esegue l'override IDisableCookieRedirectMetadata indipendentemente dall'ordine in cui vengono aggiunti i metadati. La chiamata DisableCookieRedirect dopo AllowCookieRedirect nello stesso endpoint non ripristina il comportamento del codice di stato.
Rifiutare esplicitamente il comportamento a livello di app
Per ripristinare il comportamento di pre-.NET 10 per un'intera app, abilitare l'opzioneMicrosoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata. Quando è abilitata, cookie l'autenticazione ignora i metadati degli endpoint e solo le richieste XHR generano risposte 401 e 403.
Impostare l'opzione nel file di progetto in modo che venga applicata prima dell'esecuzione di qualsiasi codice dell'app:
<ItemGroup>
<RuntimeHostConfigurationOption
Include="Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata"
Value="true" />
</ItemGroup>
L'opzione può essere impostata anche nel codice. Viene letto una sola volta, la prima volta che viene usata cookie l'autenticazione, quindi è necessario chiamare SetSwitch prima che venga costruito l'host:
AppContext.SetSwitch(
"Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata", true);
var builder = WebApplication.CreateBuilder(args);
Considerazioni di rilievo sulle modifiche
La modifica introdotta in .NET 10 è un cambiamento comportamentale. Un'app che combina l'autenticazione cookie con endpoint che ASP.NET Core rileva come endpoint API restituisce risposte 401 e 403 laddove in precedenza restituiva un reindirizzamento 302 alla pagina di accesso o di accesso negato. Per l'avviso completo relativo alla modifica che causa un'interruzione, vedere Cookie i reindirizzamenti di accesso sono disabilitati per gli endpoint API noti.
Considerare l'impatto su ogni tipo di app:
- Applicazioni web: gli endpoint delle pagine continuano a reindirizzare alla pagina di accesso.
- Applicazioni miste: gli endpoint API restituiscono codici di stato mentre le pagine Web ottengono i reindirizzamenti, quindi il codice del browser che ha seguito il reindirizzamento deve gestire invece 401 e 403.
- Applicazioni solo API: gli endpoint API rilevati restituiscono codici di stato HTTP appropriati senza configurazione aggiuntiva.
Per mantenere il comportamento precedente, chiamare AllowCookieRedirect gli endpoint interessati, applicare [AllowCookieRedirect] ai controller interessati o abilitare l'opzione Microsoft.AspNetCore.Authentication.Cookies.IgnoreRedirectMetadata per l'intera app.
Test degli endpoint API
Dopo l'aggiornamento a ASP.NET Core in .NET 10, verificare che gli endpoint API restituisca codici di stato appropriati:
[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);
}