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.
In questo articolo vengono create applicazioni daemon, servizi in background e agenti autonomi usando Microsoft. Identity.Web. Queste applicazioni vengono eseguite senza interazione dell'utente ed eseguono l'autenticazione usando l'identità dell'applicazione (credenziali client) o le identità dell'agente.
Informazioni sugli scenari supportati
Microsoft. Identity.Web supporta tre tipi di applicazioni non interattive:
| Scenario | Tipo di autenticazione | Tipo di token | Caso d'uso |
|---|---|---|---|
| Standard Daemon | Credenziali client (segreto/certificato) | Token di accesso solo per app | Servizi in background, processi pianificati, elaborazione dati |
| Agente autonomo | Identità agente con credenziali client | Token di accesso solo per app per l'agente | Agenti Copilot, servizi autonomi che agiscono per conto di un'identità di agente. (in genere in un'API Web protetta) |
| Identità utente agente | Identità utente agente | Identità dell'utente agente con credenziali del client | Servizi autonomi che agiscono per conto di un'identità utente di Agent. (in genere in un'API Web protetta) |
Get started
Prerequisiti
Prima di iniziare, assicurarsi di avere:
- .NET 8.0 o versione successiva
- Microsoft Entra registrazione dell'app con credenziali del client (segreto della chiave client o certificato)
- Per scenari relativi agli agenti: identità dell'agente configurate nel tenant Microsoft Entra
Installare i pacchetti
Aggiungere i pacchetti NuGet necessari al progetto:
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Extensions.Hosting
Scegliere un approccio di configurazione
Microsoft. Identity.Web offre due modi per configurare le applicazioni daemon:
Opzione 1: TokenAcquirerFactory (consigliato per scenari semplici)
Ideale per: Prototipi rapidi, app console, test e semplici servizi daemon.
Il codice seguente crea un TokenAcquirerFactory, configura le API downstream e Microsoft Graph e chiama il API Graph:
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
// Get the token acquirer factory instance
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
// Configure downstream API and Microsoft Graph (optional)
tokenAcquirerFactory.Services.AddDownstreamApis(
tokenAcquirerFactory.Configuration.GetSection("DownstreamApis"))
.AddMicrosoftGraph();
var serviceProvider = tokenAcquirerFactory.Build();
// Call Microsoft Graph
var graphClient = serviceProvider.GetRequiredService<GraphServiceClient>();
var users = await graphClient.Users.GetAsync();
Vantaggi:
- Codice boilerplate minimo
- Carica automaticamente
appsettings.json - Perfetto per scenari semplici
- Inizializzazione in una riga
Svantaggi:
- Non adatto per i test in esecuzione in parallelo (singleton)
Opzione 2: Full ServiceCollection (scelta consigliata per l'ambiente di produzione)
Ideale per: Applicazioni di produzione, scenari complessi, inserimento delle dipendenze, testability.
Il codice seguente usa l'host generico .NET per configurare l'autenticazione, l'acquisizione di token, la memorizzazione nella cache e un servizio in background:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Web;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
// Configure authentication
services.Configure<MicrosoftIdentityApplicationOptions>(
context.Configuration.GetSection("AzureAd"));
// Add token acquisition (true = singleton lifetime)
services.AddTokenAcquisition(true);
// Add token cache (in-memory for development)
services.AddInMemoryTokenCaches();
// Add HTTP client for API calls
services.AddHttpClient();
// Add Microsoft Graph (optional)
services.AddMicrosoftGraph();
// Add your background service
services.AddHostedService<DaemonWorker>();
})
.Build();
await host.RunAsync();
Vantaggi:
- Controllo completo sui provider di configurazione
- Maggiore testabilità con l'iniezione di costruttore
- Si integra con il modello di hosting di ASP.NET Core
- Supporta scenari complessi (più schemi di autenticazione)
- Architettura pronta per la produzione
- Supporta l'esecuzione parallela dei test (provider di servizi isolati per ciascun test)
Annotazioni
Il parametro true in AddTokenAcquisition(true) indica che il servizio viene registrato come singleton (istanza singola per la durata dell'app). Usare false per la durata con ambito nelle applicazioni Web.
Raccomandazione: Iniziare con
TokenAcquirerFactoryper i prototipi e i test a thread singolo. Eseguire la migrazione al modello completoServiceCollectiondurante la compilazione di applicazioni di produzione o l'esecuzione di test paralleli.
Configurare applicazioni daemon standard
Le applicazioni daemon standard eseguono l'autenticazione usando credenziali client (segreto client o certificato) e ottengono token di accesso solo app per chiamare le API.
Configurare impostazioni di autenticazione
Aggiungere la configurazione seguente al file appsettings.json . È possibile usare un segreto client o un certificato (consigliato per la produzione):
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"ClientCredentials": [
// Option 1: Client Secret
{
"SourceType": "ClientSecret",
"ClientSecret": "your-client-secret",
},
// Option 2: Certificate (recommended for production)
{
"SourceType": "StoreWithDistinguishedName",
"CertificateStorePath": "CurrentUser/My",
"CertificateDistinguishedName": "CN=DaemonAppCert"
}
// More options: https://aka.ms/ms-id-web/client-credentials
]
}
}
Importante: Impostare il appsettings.json per copiare nella directory di output. Aggiungere quanto segue al .csproj file:
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
ASP.NET Core le applicazioni copiano automaticamente questo file, ma le app daemon (e le app OWIN) non lo fanno.
Configurare la configurazione del servizio
Il codice seguente Program.cs registra le opzioni di Microsoft Identity, l'acquisizione dei token, il caching e un servizio in background ospitato.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Web;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
IConfiguration configuration = context.Configuration;
// Configure Microsoft Identity options
services.Configure<MicrosoftIdentityApplicationOptions>(
configuration.GetSection("AzureAd"));
// Add token acquisition (true = singleton)
services.AddTokenAcquisition(true);
// Add token cache
services.AddInMemoryTokenCaches(); // For development
// services.AddDistributedTokenCaches(); // For production
// Add HTTP client
services.AddHttpClient();
// Add Microsoft Graph SDK (optional)
services.AddMicrosoftGraph();
// Add your background service
services.AddHostedService<DaemonWorker>();
})
.Build();
await host.RunAsync();
Chiamare Microsoft Graph
La classe DaemonWorker.cs seguente usa Graph SDK per elencare gli utenti in base a una pianificazione ricorrente:
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Graph;
using Microsoft.Identity.Abstractions;
public class DaemonWorker : BackgroundService
{
private readonly GraphServiceClient _graphClient;
private readonly ILogger<DaemonWorker> _logger;
public DaemonWorker(
GraphServiceClient graphClient,
ILogger<DaemonWorker> logger)
{
_graphClient = graphClient;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
// Call Microsoft Graph with app-only permissions
var users = await _graphClient.Users
.GetAsync(cancellationToken: stoppingToken);
_logger.LogInformation($"Found {users?.Value?.Count} users");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error calling Microsoft Graph");
}
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
}
}
}
Utilizzare IAuthorizationHeaderProvider
Per un maggiore controllo sulle chiamate HTTP, usare IAuthorizationHeaderProvider per creare manualmente le intestazioni di autorizzazione:
using Microsoft.Identity.Abstractions;
public class DaemonService
{
private readonly IAuthorizationHeaderProvider _authProvider;
private readonly HttpClient _httpClient;
public DaemonService(
IAuthorizationHeaderProvider authProvider,
IHttpClientFactory httpClientFactory)
{
_authProvider = authProvider;
_httpClient = httpClientFactory.CreateClient();
}
public async Task<string> CallApiAsync()
{
// Get authorization header for app-only access
string authHeader = await _authProvider
.CreateAuthorizationHeaderForAppAsync(
scopes: "https://graph.microsoft.com/.default");
// Add to HTTP request
_httpClient.DefaultRequestHeaders.Clear();
_httpClient.DefaultRequestHeaders.Add("Authorization", authHeader);
var response = await _httpClient.GetStringAsync(
"https://graph.microsoft.com/v1.0/users");
return response;
}
}
Vedere anche Calling downstream API per informazioni su tutti i modi in cui Microsoft Identity Web propone di chiamare LE API downstream.
Configurare agenti autonomi (identità agente)
Gli agenti autonomi usano le identità degli agenti per ottenere token solo per app. Questo modello è utile nei scenari di Copilot e nei servizi autonomi.
Annotazioni
Microsoft consiglia agli agenti di chiamare LE API downstream dall'interno di API Web protette, anche quando gli agenti acquisiscono un token dell'app.
Configurare i servizi dell'agente
Il codice seguente configura l'autenticazione, l'acquisizione di token e il supporto dell'identità dell'agente usando la configurazione in memoria:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Identity.Web;
var services = new ServiceCollection();
// Configuration
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["AzureAd:Instance"] = "https://login.microsoftonline.com/",
["AzureAd:TenantId"] = "your-tenant-id",
["AzureAd:ClientId"] = "your-agent-app-client-id",
["AzureAd:ClientCredentials:0:SourceType"] = "StoreWithDistinguishedName",
["AzureAd:ClientCredentials:0:CertificateStorePath"] = "CurrentUser/My",
["AzureAd:ClientCredentials:0:CertificateDistinguishedName"] = "CN=YourCert"
})
.Build();
services.AddSingleton<IConfiguration>(configuration);
// Configure Microsoft Identity
services.Configure<MicrosoftIdentityApplicationOptions>(
configuration.GetSection("AzureAd"));
services.AddTokenAcquisition(true);
services.AddInMemoryTokenCaches();
services.AddHttpClient();
services.AddMicrosoftGraph();
// Add agent identities support
services.AddAgentIdentities();
var serviceProvider = services.BuildServiceProvider();
Acquisire token utilizzando l'identità dell'agente
Dopo aver configurato i servizi agente, acquisire i token usando IAuthorizationHeaderProvider o Microsoft Graph SDK:
using Microsoft.Identity.Abstractions;
using Microsoft.Graph;
// Your agent identity GUID
string agentIdentityId = "d84da24a-2ea2-42b8-b5ab-8637ec208024";
// Option 1: Using IAuthorizationHeaderProvider
IAuthorizationHeaderProvider authProvider =
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
var options = new AuthorizationHeaderProviderOptions()
.WithAgentIdentity(agentIdentityId);
string authHeader = await authProvider.CreateAuthorizationHeaderForAppAsync(
scopes: "https://graph.microsoft.com/.default",
options);
// Option 2: Using Microsoft Graph SDK
GraphServiceClient graphClient =
serviceProvider.GetRequiredService<GraphServiceClient>();
var applications = await graphClient.Applications.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(authOptions =>
{
authOptions.WithAgentIdentity(agentIdentityId);
});
});
Esaminare un esempio completo di agente autonomo
La seguente classe incapsula l'acquisizione del token di identità dell'agente e le chiamate API Graph in un servizio riutilizzabile.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Graph;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
public class AutonomousAgentService
{
private readonly GraphServiceClient _graphClient;
private readonly IAuthorizationHeaderProvider _authProvider;
private readonly string _agentIdentityId;
public AutonomousAgentService(
string agentIdentityId,
IServiceProvider serviceProvider)
{
_agentIdentityId = agentIdentityId;
_graphClient = serviceProvider.GetRequiredService<GraphServiceClient>();
_authProvider = serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
}
public async Task<string> GetAuthorizationHeaderAsync()
{
var options = new AuthorizationHeaderProviderOptions()
.WithAgentIdentity(_agentIdentityId);
return await _authProvider.CreateAuthorizationHeaderForAppAsync(
"https://graph.microsoft.com/.default",
options);
}
public async Task<IEnumerable<Application>> ListApplicationsAsync()
{
var apps = await _graphClient.Applications.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
{
options.WithAgentIdentity(_agentIdentityId);
});
});
return apps?.Value ?? Enumerable.Empty<Application>();
}
}
Configurare l'identità utente dell'agente
L'identità utente agente consente agli agenti di agire per conto di un utente agente con autorizzazioni delegate. Usare questo modello per gli agenti che necessitano della propria cassetta postale o di altre risorse con ambito utente.
Prerequisiti
Per usare l'identità utente dell'agente, è necessario:
- Progetto agent registrato in Microsoft Entra ID
- Identità dell'agente creata e collegata all'applicazione agente
- Identità utente agente associata all'identità dell'agente
Configurare i servizi utente dell'agente
Il codice seguente configura l'identità dell'applicazione agente con una credenziale del certificato e registra i servizi necessari:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Web;
using System.Security.Cryptography.X509Certificates;
var services = new ServiceCollection();
// Configure agent application
services.Configure<MicrosoftIdentityApplicationOptions>(options =>
{
options.Instance = "https://login.microsoftonline.com/";
options.TenantId = "your-tenant-id";
options.ClientId = "your-agent-app-client-id";
// Use certificate for agent authentication
options.ClientCredentials = new[]
{
CertificateDescription.FromStoreWithDistinguishedName(
"CN=YourCertificate",
StoreLocation.CurrentUser,
StoreName.My)
};
});
// Add services (true = singleton)
services.AddSingleton<IConfiguration>(new ConfigurationBuilder().Build());
services.AddTokenAcquisition(true);
services.AddInMemoryTokenCaches();
services.AddHttpClient();
services.AddMicrosoftGraph();
services.AddAgentIdentities();
var serviceProvider = services.BuildServiceProvider();
Acquisire i token utente con l'identità dell'agente
È possibile identificare l'utente di destinazione in base all'UPN o all'ID oggetto.
Per nome utente (UPN)
using Microsoft.Identity.Abstractions;
using Microsoft.Graph;
string agentIdentityId = "your-agent-identity-id";
string userUpn = "user@yourtenant.onmicrosoft.com";
// Get authorization header
IAuthorizationHeaderProvider authProvider =
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
var options = new AuthorizationHeaderProviderOptions()
.WithAgentUserIdentity(
agentApplicationId: agentIdentityId,
username: userUpn);
string authHeader = await authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options);
// Or use Microsoft Graph SDK
GraphServiceClient graphClient =
serviceProvider.GetRequiredService<GraphServiceClient>();
var me = await graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
options.WithAgentUserIdentity(agentIdentityId, userUpn));
});
Id oggetto utente
string agentIdentityId = "your-agent-identity-id";
Guid userObjectId = Guid.Parse("user-object-id");
var options = new AuthorizationHeaderProviderOptions()
.WithAgentUserIdentity(
agentApplicationId: agentIdentityId,
userId: userObjectId);
string authHeader = await authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options);
// With Graph SDK
var me = await graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
options.WithAgentUserIdentity(agentIdentityId, userObjectId));
});
Memorizzare nella cache i token con ClaimsPrincipal
Per prestazioni migliori, memorizzare nella cache i token utente passando un'istanza ClaimsPrincipal . La prima chiamata popola il principale con le attestazioni uid e utid; le chiamate successive riutilizzano il token memorizzato nella cache.
using System.Security.Claims;
using Microsoft.Identity.Abstractions;
// First call - creates cache entry
ClaimsPrincipal userPrincipal = new ClaimsPrincipal();
string authHeader = await authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options,
userPrincipal);
// ClaimsPrincipal now has uid and utid claims for caching
bool hasUserId = userPrincipal.HasClaim(c => c.Type == "uid");
bool hasTenantId = userPrincipal.HasClaim(c => c.Type == "utid");
// Subsequent calls - uses cache
authHeader = await authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options,
userPrincipal); // Reuse the same principal
Eseguire l'override del tenant
Per gli scenari multi-tenant, è possibile eseguire l'override del tenant in fase di esecuzione. Ciò è utile quando l'app è configurata con "common" ma deve avere come destinazione un tenant specifico:
var options = new AuthorizationHeaderProviderOptions()
.WithAgentUserIdentity(agentIdentityId, userUpn);
// Override tenant (useful when app is configured with "common")
options.AcquireTokenOptions.Tenant = "specific-tenant-id";
string authHeader = await authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options);
// With Graph SDK
var me = await graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
{
options.WithAgentUserIdentity(agentIdentityId, userUpn);
options.AcquireTokenOptions.Tenant = "specific-tenant-id";
});
});
Esaminare un esempio completo di identità utente di un agente
La classe seguente fornisce metodi per ottenere i profili utente e le intestazioni di autorizzazione usando l'identità utente dell'agente:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Graph;
using Microsoft.Identity.Abstractions;
using System.Security.Claims;
public class AgentUserService
{
private readonly IAuthorizationHeaderProvider _authProvider;
private readonly GraphServiceClient _graphClient;
private readonly string _agentIdentityId;
public AgentUserService(
string agentIdentityId,
IServiceProvider serviceProvider)
{
_agentIdentityId = agentIdentityId;
_authProvider = serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
_graphClient = serviceProvider.GetRequiredService<GraphServiceClient>();
}
public async Task<User> GetUserProfileAsync(string userUpn)
{
var me = await _graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
options.WithAgentUserIdentity(_agentIdentityId, userUpn));
});
return me!;
}
public async Task<User> GetUserProfileByIdAsync(Guid userObjectId)
{
var me = await _graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
options.WithAgentUserIdentity(_agentIdentityId, userObjectId));
});
return me!;
}
public async Task<string> GetAuthHeaderForUserAsync(
string userUpn,
ClaimsPrincipal? cachedPrincipal = null)
{
var options = new AuthorizationHeaderProviderOptions()
.WithAgentUserIdentity(_agentIdentityId, userUpn);
return await _authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options,
cachedPrincipal ?? new ClaimsPrincipal());
}
}
Creare una configurazione del servizio riutilizzabile
Definire un metodo di estensione
Creare un metodo di estensione riutilizzabile per incapsulare la configurazione dell'identità dell'agente nell'applicazione:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
public static class ServiceCollectionExtensions
{
public static IServiceProvider ConfigureServicesForAgentIdentities(
this IServiceCollection services,
IConfiguration configuration)
{
// Add configuration
services.AddSingleton(configuration);
// Configure Microsoft Identity options
services.Configure<MicrosoftIdentityApplicationOptions>(
configuration.GetSection("AzureAd"));
services.AddTokenAcquisition(true);
// Add token caching
services.AddInMemoryTokenCaches();
// Add HTTP client
services.AddHttpClient();
// Add Microsoft Graph (optional)
services.AddMicrosoftGraph();
// Add agent identities support
services.AddAgentIdentities();
return services.BuildServiceProvider();
}
}
Usare il metodo di estensione
Chiamare il metodo di estensione per configurare i servizi in una singola riga:
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var serviceProvider = services.ConfigureServicesForAgentIdentities(configuration);
Chiamare le API
Questa sezione illustra come chiamare le API usando ognuno dei tre modelli di autenticazione.
Chiamare Microsoft Graph
Gli esempi seguenti illustrano la chiamata Microsoft Graph come daemon standard, un agente autonomo e un'identità utente agente:
using Microsoft.Graph;
GraphServiceClient graphClient =
serviceProvider.GetRequiredService<GraphServiceClient>();
// Standard daemon (app-only)
var users = await graphClient.Users.GetAsync();
// Autonomous agent (app-only with agent identity)
var apps = await graphClient.Applications.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
{
options.WithAgentIdentity("agent-identity-id");
options.RequestAppToken = true;
});
});
// Agent user identity (delegated with user context)
var me = await graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
options.WithAgentUserIdentity("agent-identity-id", "user@tenant.com"));
});
Chiamare API personalizzate con IDownstreamApi
Usare IDownstreamApi per chiamare le PROPRIE API protette con uno dei tre modelli di autenticazione seguenti:
using Microsoft.Identity.Abstractions;
IDownstreamApi downstreamApi =
serviceProvider.GetRequiredService<IDownstreamApi>();
// Standard daemon
var result = await downstreamApi.GetForAppAsync<ApiResponse>(
serviceName: "MyApi",
options => options.RelativePath = "api/data");
// With agent identity
var result = await downstreamApi.GetForAppAsync<ApiResponse>(
serviceName: "MyApi",
options =>
{
options.RelativePath = "api/data";
options.WithAgentIdentity("agent-identity-id");
});
// Agent user identity
var result = await downstreamApi.GetForUserAsync<ApiResponse>(
serviceName: "MyApi",
options =>
{
options.RelativePath = "api/data";
options.WithAgentUserIdentity("agent-identity-id", "user@tenant.com");
});
Effettuare chiamate HTTP manuali
Usare IAuthorizationHeaderProvider direttamente quando è necessario il controllo completo sulle richieste HTTP:
using Microsoft.Identity.Abstractions;
IAuthorizationHeaderProvider authProvider =
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
HttpClient httpClient = new HttpClient();
// Standard daemon
string authHeader = await authProvider.CreateAuthorizationHeaderForAppAsync(
"https://graph.microsoft.com/.default");
httpClient.DefaultRequestHeaders.Add("Authorization", authHeader);
var response = await httpClient.GetStringAsync("https://graph.microsoft.com/v1.0/users");
// With agent identity
var options = new AuthorizationHeaderProviderOptions()
.WithAgentIdentity("agent-identity-id");
authHeader = await authProvider.CreateAuthorizationHeaderForAppAsync(
"https://graph.microsoft.com/.default",
options);
// Agent user identity
var userOptions = new AuthorizationHeaderProviderOptions()
.WithAgentUserIdentity("agent-identity-id", "user@tenant.com");
authHeader = await authProvider.CreateAuthorizationHeaderForUserAsync(
new[] { "https://graph.microsoft.com/.default" },
userOptions);
Configurare la memorizzazione nella cache dei token
Scegliere una strategia di memorizzazione nella cache in base all'ambiente in uso.
Sviluppo: cache in memoria
Utilizzare l'in-memory caching per lo sviluppo e il collaudo locale.
services.AddInMemoryTokenCaches();
Produzione: cache distribuita
Per l'ambiente di produzione, usare una cache distribuita per rendere persistenti i token tra i riavvii e le istanze di scalabilità orizzontale.
SQL Server
Archiviare i token in una tabella di SQL Server.
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = configuration["ConnectionStrings:TokenCache"];
options.SchemaName = "dbo";
options.TableName = "TokenCache";
});
services.AddDistributedTokenCaches();
Redis
Usare Redis per la memorizzazione nella cache dei token distribuiti a prestazioni elevate:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["Redis:ConnectionString"];
options.InstanceName = "TokenCache_";
});
services.AddDistributedTokenCaches();
Cosmos DB
Usare Cosmos DB per la memorizzazione nella cache dei token distribuiti a livello globale:
services.AddCosmosDbTokenCaches(options =>
{
options.CosmosDbConnectionString = configuration["CosmosDb:ConnectionString"];
options.DatabaseId = "TokenCache";
options.ContainerId = "Tokens";
});
Altre informazioni:Configurazione della cache dei token
Esplorare gli esempi di Azure
Microsoft fornisce esempi che illustrano i modelli di app daemon.
Repository di esempio
active-directory-dotnetcore-daemon-v2
Questo repository contiene più scenari:
| Esempio | Descrizione | Link |
|---|---|---|
| 1-Call-MSGraph | Daemon di base che chiama Microsoft Graph con credenziali client | Visualizza esempio |
| 2-Call-OwnApi | Daemon che chiama la tua API Web protetta | Visualizza esempio |
| 3-Using-KeyVault | Daemon con Azure Key Vault per l'archiviazione dei certificati | Visualizza esempio |
| 4-Multi-Tenant | Applicazione daemon multi-tenant | Visualizza esempio |
| 5-Call-MSGraph-ManagedIdentity | Daemon che usa l'identità gestita in Azure | Visualizza esempio |
Confrontare modelli di esempio con modelli di produzione
Gli esempi di Azure usano TokenAcquirerFactory.GetDefaultInstance() per semplicità, ovvero l'approccio consigliato per le app console simple, i prototipi e i test. Questa guida illustra entrambi i modelli:
Modello TokenAcquirerFactory (Azure Samples):
// Simple, perfect for prototypes and tests
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi("MyApi", ...);
var serviceProvider = tokenAcquirerFactory.Build();
Full ServiceCollection Pattern (per applicazioni di produzione):
// More control, testable, follows DI best practices
var services = new ServiceCollection();
services.AddTokenAcquisition(true); // true = singleton
services.Configure<MicrosoftIdentityApplicationOptions>(...);
var serviceProvider = services.BuildServiceProvider();
Quando usare quale:
-
Utilizzare
TokenAcquirerFactoryper: app console, prototipi rapidi, unit test, servizi daemon semplici -
Usare
ServiceCollectionper: applicazioni di produzione, integrazione ASP.NET Core, scenari di inserimento delle dipendenze complessi, servizi in background conIHostedService
Entrambi gli approcci sono completamente supportati e pronti per la produzione. Scegliere in base alle esigenze di complessità e integrazione dell'applicazione.
Risolvere gli errori comuni
AADSTS700016: applicazione non trovata
Causa: Non valido ClientId o l'applicazione non è registrata nel tenant.
Solution: Verificare che il ClientId nella configurazione corrisponda alla registrazione dell'app Microsoft Entra.
AADSTS7000215: Client Secret non valido
Causa: Il segreto client non è corretto, è scaduto o non è configurato.
Soluzione:
- Verificare che il segreto nel portale di Azure corrisponda alla configurazione
- Controllare la data di scadenza del segreto
- Prendere in considerazione l'uso dei certificati per la produzione
AADSTS700027: l'asserzione client contiene una firma non valida
Causa: Certificato non trovato, scaduto o chiave privata non accessibile.
Soluzione:
- Verificare che il certificato sia installato nell'archivio certificati corretto
- Controllare che il nome distinto del certificato corrisponda alla configurazione
- Verificare che l'applicazione disponga dell'autorizzazione per leggere la chiave privata
- Vedere La Guida alla configurazione dei certificati
AADSTS650052: l'app deve accedere a un servizio
Causa: Autorizzazioni API necessarie non concesse o consenso amministratore mancante.
Soluzione:
- Passare al portale di Azure → Registrazioni app → Autorizzazioni API per l'app →
- Aggiungere le autorizzazioni necessarie (ad esempio,
User.Read.Allper Microsoft Graph) - Fare clic sul pulsante "Concedi consenso amministratore"
Errori di identità dell'agente
AADSTS50105: l'utente connesso non è assegnato a un ruolo
Causa: Identità dell'agente non configurata correttamente o non assegnata all'applicazione.
Soluzione:
- Verificare che l'identità dell'agente esista in Microsoft Entra ID
- Verificare che l'identità dell'agente sia collegata all'applicazione
- Verificare che l'identità dell'agente disponga delle autorizzazioni necessarie
Token acquisiti ma con autorizzazioni errate
Causa: Uso dell'identità utente dell'agente ma richiesta di autorizzazioni dell'app o viceversa.
Soluzione:
- Per token riservati ad app: usare
CreateAuthorizationHeaderForAppAsyncconWithAgentIdentity - Per i token delegati: usare
CreateAuthorizationHeaderForUserAsyncconWithAgentUserIdentity - Verificare che le autorizzazioni API corrispondano al tipo di token (applicazione e delegata)
Problemi di memorizzazione nella cache dei token
Problema: I token non vengono memorizzati nella cache, che forzano ogni volta una nuova acquisizione.
Soluzione:
- Per l'identità utente dell'agente: riutilizzare la stessa
ClaimsPrincipalistanza tra le chiamate - Verificare la connessione alla cache distribuita (se si usa Redis/SQL)
- Abilitare la registrazione di debug per visualizzare le operazioni della cache
Diagnostica dettagliata:Guida alla registrazione e alla diagnostica
Contenuti correlati
- Chiamata di API downstream dalle API Web - Modelli OBO
- Guida al framework MSAL.NET - Configurazione della cache dei token e del certificato per .NET Framework
- Configurazione certificato - Caricamento di certificati da Key Vault, archivio, file o Base64
- Configurazione della cache dei token - Strategie di memorizzazione nella cache di produzione
- Registrazione e diagnostica - Risolvere i problemi di acquisizione dei token
- Guida alla personalizzazione - Modelli di configurazione avanzati
- Documentazione dell'applicazione daemon della piattaforma di identità Microsoft
- esempi di Azure: applicazioni daemon
- Microsoft. Pacchetto NuGet Identity.Web
- Riferimento API Microsoft.Identity.Abstractions