Guida introduttiva: Proteggere un'API Web ASP.NET Core

In questa guida introduttiva si protegge un'API Web ASP.NET Core con Microsoft Entra ID usando Microsoft.Identity.Web. Si aggiunge il middleware di autenticazione che convalida i token di connessione e limita l'accesso ai chiamanti autorizzati.

Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare.

Prerequisiti

Opzione 1: Crea da un modello (più veloce)

Usare il modello di ASP.NET Core con l'autenticazione Microsoft Entra predefinita per eseguire lo scaffolding di un progetto API protetto.

1. Creare il progetto

Eseguire i comandi seguenti per creare un nuovo progetto API Web con autenticazione a singola organizzazione e passare alla directory del progetto:

dotnet new webapi --auth SingleOrg --name MyWebApi
cd MyWebApi

2. Configurare la registrazione dell'app

Sostituire i valori segnaposto in appsettings.json con i dettagli di registrazione dell'app Microsoft Entra:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  }
}

3. Eseguire l'API

Avviare l'applicazione:

dotnet run

L'API è ora protetta in https://localhost:5001.

Fatto! Le richieste richiedono ora un token di accesso valido.


Opzione 2: Aggiungere all'API Web esistente

Se si dispone già di un'API Web ASP.NET Core, aggiungere l'autenticazione Microsoft Entra seguendo questi passaggi.

1. Installare il pacchetto NuGet

Aggiungere il pacchetto NuGet Microsoft.Identity.Web al progetto:

dotnet add package Microsoft.Identity.Web

2. Configurare l'autenticazione in Program.cs

Registrare i servizi di autenticazione e autorizzazione nella pipeline di avvio dell'app. Il codice seguente configura l'autenticazione JWT Bearer con la convalida di Microsoft Entra.

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// Add authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApi(builder.Configuration, "AzureAd");

// Add authorization
builder.Services.AddAuthorization();

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthentication(); //  Add authentication middleware
app.UseAuthorization();

app.MapControllers();

app.Run();

3. Aggiungere la configurazione a appsettings.json

Aggiungere la sezione di configurazione Microsoft Entra con i dettagli del tenant e dell'applicazione. Impostare il livello di registrazione per Microsoft.Identity.Web su Information per risolvere i problemi di convalida dei token:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Identity.Web": "Information"
    }
  }
}

4. Proteggere gli endpoint API

Applicare l'attributo [Authorize] ai controller o alle azioni che richiedono un token di accesso valido.

Richiedere l'autenticazione per tutti gli endpoint:

Il controller seguente richiede un token di accesso valido per tutte le azioni e mostra come accedere alle attestazioni utente:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[Authorize] //  Require valid access token
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        // Access user information
        var userId = User.FindFirst("oid")?.Value;
        var userName = User.Identity?.Name;

        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = "Protected data"
        });
    }
}

Richiedi ambiti specifici:

Usare l'attributo [RequiredScope] per applicare autorizzazioni con granularità fine per le singole azioni:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class TodoController : ControllerBase
{
    [HttpGet]
    [RequiredScope("access_as_user")] //  Require specific scope
    public IActionResult GetAll()
    {
        return Ok(new[] { "Todo 1", "Todo 2" });
    }

    [HttpPost]
    [RequiredScope("write")] //  Different scope for write operations
    public IActionResult Create([FromBody] string item)
    {
        return Created("", item);
    }
}

5. Eseguire e testare

Avviare l'applicazione e verificare che le richieste non autenticate vengano rifiutate:

dotnet run

Prova uno strumento come Postman o curl. Una richiesta non autenticata restituisce 401 Unauthorized:

curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://localhost:5001/api/weatherforecast

Successo! L'API convalida ora i token di connessione.


Configurazione della registrazione dell'app

Prima che l'API possa convalidare i token, è necessaria una registrazione dell'app Microsoft Entra. Seguire questa procedura nel portale di Azure.

1. Registrare l'API

  1. Accedere al portale di Azure
  2. Passare a Microsoft Entra ID>Registrazioni app>Nuova registrazione
  3. Immettere un nome (ad esempio, "La mia API Web")
  4. Selezionare Tenant singolo (più comune per le API)
  5. Nessun URI di reindirizzamento necessario per le API
  6. Fare clic su Registra

2. Esporre un ambito dell'API

Definire le autorizzazioni (ambiti) che le app client possono richiedere quando si chiama l'API.

  1. Nella registrazione dell'app per le API passare a Esporre un'API
  2. Fare clic su Aggiungi un ambito
  3. Accettare l'URI id applicazione predefinito o personalizzarlo (ad esempio, api://your-api-client-id)
  4. Aggiungere un ambito:
    • Nome ambito:access_as_user
    • Chi può fornire il consenso: Amministratori e utenti
    • Nome visualizzato del consenso amministratore: "Accedi alla mia API Web"
    • Descrizione del consenso amministratore: "Consente all'app di accedere all'API Web per conto dell'utente connesso"
  5. Fare clic su Aggiungi ambito

3. Prendere nota dell'ID applicazione

Copiare l'ID applicazione (client) dalla pagina di panoramica della registrazione dell'app. Questo valore è il ClientId in appsettings.json.


Creare una registrazione dell'app client (per i test)

Per testare l'API protetta, registrare un'applicazione client separata che acquisisce i token e chiama l'API.

1. Registrare un'applicazione client

  1. In Microsoft Entra ID>Registrazioni app creare un'altra registrazione
  2. Denominarlo (ad esempio, "Client API personale")
  3. Selezionare i tipi di account
  4. Aggiungere l'URI di reindirizzamento: https://localhost:7000/signin-oidc (se si tratta di un'app Web)
  5. Fare clic su Registra

2. Concedere autorizzazioni API

Concedere all'applicazione client l'autorizzazione per chiamare l'API con gli ambiti definiti.

  1. Nella registrazione dell'app client passare a Autorizzazioni API
  2. Fare clic su Aggiungi un'autorizzazione>Api personali
  3. Selezionare la registrazione dell'API
  4. Controllare l'ambito access_as_user
  5. Fare clic su Aggiungi autorizzazioni
  6. Fare clic su Concedi consenso amministratore (se necessario)

3. Creare un segreto client (per i client riservati)

Se l'app client viene eseguita in un server (non in un browser o in un dispositivo mobile), creare un segreto client per l'autenticazione.

  1. Vai a Certificati e segreti
  2. Clicca su Nuovo segreto del client
  3. Aggiungere una descrizione e una scadenza
  4. Fare clic su Aggiungi
  5. Copiare immediatamente il valore del segreto : non sarà possibile visualizzarlo di nuovo

Testare l'API protetta

Verificare che l'API convalide correttamente i token inviando richieste autenticate.

Utilizzo di Postman

Configurare l'autenticazione OAuth 2.0 in Postman per acquisire un token e chiamare l'API.

  1. Creare una nuova richiesta in Postman
  2. Configurare l'autenticazione OAuth 2.0:
    • Tipo di concessione: Codice di autorizzazione (per il contesto utente) o Credenziali client (per il contesto dell'app)
    • URL di autenticazione:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize
    • URL del token di accesso:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
    • ID client: ID cliente della tua app cliente
    • Segreto del client: Segreto dell'applicazione client
    • Ambito:api://your-api-client-id/access_as_user
  3. Fare clic su Ottieni nuovo token di accesso
  4. Usare il token per chiamare l'API

Uso del codice (esempio C#)

L'esempio seguente usa MSAL.NET per acquisire un token con il flusso delle credenziali client e chiamare l'API protetta:

// In a console app or client application
using Microsoft.Identity.Client;

var app = ConfidentialClientApplicationBuilder
    .Create("client-app-id")
    .WithClientSecret("client-secret")
    .WithAuthority("https://login.microsoftonline.com/{tenant-id}")
    .Build();

var result = await app.AcquireTokenForClient(
    new[] { "api://your-api-client-id/.default" }
).ExecuteAsync();

var accessToken = result.AccessToken;

// Use the token to call your API
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

var response = await client.GetAsync("https://localhost:5001/api/weatherforecast");

Opzioni di configurazione comuni

Microsoft. Identity.Web supporta diversi modelli di configurazione per diversi scenari.

Richiedere ambiti specifici nella configurazione

Anziché usare l'attributo [RequiredScope] , è possibile configurare gli ambiti necessari a livello globale in appsettings.json:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id",
    "Scopes": "access_as_user"
  }
}

Accettare i token da più tenenti

Per accettare i token da qualsiasi tenant di Microsoft Entra, impostare TenantId su common:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "common",
    "ClientId": "your-api-client-id"
  }
}

Configurare la convalida dei token

Se l'API chiama API downstream (ad esempio Microsoft Graph), abilitare l'acquisizione dei token e configurare una cache dei token:

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi() // If your API calls other APIs
    .AddInMemoryTokenCaches();

Passaggi successivi

Ora che si dispone di un'API protetta, esaminare questi argomenti:

Risoluzione dei problemi

401 - Non autorizzato

Problema: L'API restituisce 401 anche con un token.

Possibili cause:

  • Il pubblico del token (aud dichiarazione) non corrisponde a quello della tua API ClientId
  • Il token è scaduto
  • Il token è per il locatario errato
  • Ambito obbligatorio mancante

Soluzione: Decodificare il token in jwt.ms e verificare le attestazioni. Per informazioni dettagliate sulla risoluzione dei problemi, vedere Registrazione e diagnostica .

AADSTS50013: firma non valida

Problema: La convalida della firma del token non riesce.

Soluzione: Assicurati che TenantId e ClientId siano corretti. Il token deve essere emesso dall'autorità prevista. Abilitare la registrazione dettagliata per visualizzare gli errori di convalida.

Ambiti non trovati nel token

Problema:[RequiredScope] l'attributo non funziona.

Soluzione:

  1. Verificare che l'app client disponga dell'autorizzazione per l'ambito
  2. Verificare che il consenso dell'amministratore sia stato concesso (se necessario)
  3. Vedere Guida all'autorizzazione per i modelli di convalida completi dell'ambito
  4. Verificare che l'ambito sia richiesto durante l'acquisizione del token (ad esempio api://your-api/.default, o ambiti specifici)

Vedere altre informazioni:Guida alla risoluzione dei problemi dell'API Web