Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Dans cet article, vous créez des applications démon, des services en arrière-plan et des agents autonomes à l’aide de Microsoft. Identity.Web. Ces applications s’exécutent sans interaction utilisateur et s’authentifient à l’aide d’identités d’application (informations d’identification du client) ou d’identités d’agent.
Comprendre les scénarios pris en charge
Microsoft. Identity.Web prend en charge trois types d’applications non interactives :
| Scénario | Type d’authentification | Type de jeton | Cas d'utilisation |
|---|---|---|---|
| Démon standard | Informations d’identification du client (secret/certificat) | Jeton d’accès d’application uniquement | Services en arrière-plan, travaux planifiés, traitement des données |
| Agent autonome | Identité de l’agent avec les informations d’identification du client | Jeton d’accès d’application uniquement pour l’agent | Copilot agents, services autonomes agissant au nom d’une identité d’agent. (Généralement dans une API web protégée) |
| Identité utilisateur de l’agent | Identité de l’utilisateur de l’agent | Identité utilisateur de l’agent avec les informations d’identification du client | Services autonomes agissant pour le compte d’une identité d’utilisateur agent. (Généralement dans une API web protégée) |
Commencez
Prerequisites
Avant de commencer, assurez-vous d’avoir :
- .NET 8.0 ou version ultérieure
- Microsoft Entra enregistrement de l'application avec des identifiants client (secret client ou certificat)
- Pour les scénarios d’agent : Identités d’agent configurées dans votre instance Microsoft Entra
Installer des packages
Ajoutez les packages NuGet requis à votre projet :
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Extensions.Hosting
Choisir une approche de configuration
Microsoft. Identity.Web fournit deux façons de configurer des applications démon :
Option 1 : TokenAcquirerFactory (recommandé pour les scénarios simples)
Meilleur pour : Prototypes rapides, applications console, tests et services démon simples.
Le code suivant crée un TokenAcquirerFactory, configure les API et les Microsoft Graph en aval, puis appelle le 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();
Avantages :
- Code réutilisable minimal
- Se charge automatiquement
appsettings.json - Parfait pour les scénarios simples
- Initialisation sur une ligne
Inconvénients:
- Non adapté aux tests exécutés en parallèle (singleton)
Option 2 : Full ServiceCollection (recommandé pour la production)
Meilleur pour : Applications de production, scénarios complexes, injection de dépendances, testabilité.
Le code suivant utilise l’hôte générique .NET pour configurer l’authentification, l’acquisition de jetons, la mise en cache et un service en arrière-plan :
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();
Avantages :
- Contrôle total sur les fournisseurs de configuration
- Meilleure testabilité avec injection de constructeur
- S’intègre avec ASP.NET Core modèle d’hébergement
- Prend en charge des scénarios complexes (plusieurs schémas d’authentification)
- Architecture prête pour la production
- Prend en charge l’exécution de tests parallèles (fournisseur de services isolé par test)
Note
Le paramètre trueAddTokenAcquisition(true) signifie que le service est inscrit en tant que singleton (instance unique pour la durée de vie de l’application). Utiliser false pour la durée de vie définie dans les applications web.
Recommandation : Commencez avec
TokenAcquirerFactorypour les prototypes et les tests monothread. Migrez vers le modèle completServiceCollectionlors de la génération d’applications de production ou d’exécution de tests parallèles.
Configurer des applications démon standard
Les applications démon standard s’authentifient à l’aide des informations d’identification client (secret client ou certificat) et obtiennent des jetons d’accès d’application uniquement pour appeler des API.
Configurer les paramètres d’authentification
Ajoutez la configuration suivante à votre fichier appsettings.json . Vous pouvez utiliser une clé secrète client ou un certificat (recommandé pour la production) :
{
"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
]
}
}
Important : Configurez votre appsettings.json pour copier vers le répertoire de sortie. Ajoutez ce qui suit à votre .csproj fichier :
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
ASP.NET Core applications copient automatiquement ce fichier, mais les applications démon (et les applications OWIN) ne le font pas.
Définir la configuration du service
Le code Program.cs suivant enregistre les options d'identité Microsoft, l'acquisition de jetons, la mise en cache et un service en arrière-plan hébergé.
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();
Appeler Microsoft Graph
La classe DaemonWorker.cs suivante utilise le Kit de développement logiciel (SDK) Graph pour répertorier les utilisateurs selon une planification périodique :
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);
}
}
}
Utiliser le IAuthorizationHeaderProvider
Pour plus de contrôle sur les appels HTTP, utilisez cette option IAuthorizationHeaderProvider pour créer manuellement des en-têtes d’autorisation :
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;
}
}
Consultez également Appeling en aval pour en savoir plus sur toutes les façons dont Microsoft Identity Web propose d’appeler des API en aval.
Configurer des agents autonomes (identité de l’agent)
Les agents autonomes utilisent des identités d’agent pour obtenir des jetons d’application uniquement. Ce modèle est utile pour les scénarios Copilot et les services autonomes.
Note
Microsoft recommande que les agents appelant des API en aval le font à partir d’API web protégées, même lorsque les agents obtiennent un jeton d’application.
Configurer les services d’agent
Le code suivant configure la prise en charge de l’authentification, de l’acquisition de jetons et de l’identité de l’agent à l’aide de la configuration en mémoire :
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();
Acquérir des jetons avec l’identité de l’agent
Après avoir configuré les services d’agent, achetez des jetons à l’aide de IAuthorizationHeaderProvider ou du Kit de développement logiciel (SDK) Microsoft Graph :
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);
});
});
Examiner un exemple complet d’agent autonome
La classe suivante regroupe l’acquisition de jetons d’identité de l’agent et d’appels à l’API Graph dans un service réutilisable.
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>();
}
}
Configurer l’identité utilisateur de l’agent
L’identité utilisateur de l’agent permet aux agents d’agir au nom d’un utilisateur d’agent disposant d’autorisations déléguées. Utilisez ce modèle pour les agents qui ont besoin de leur propre boîte aux lettres ou d’autres ressources étendues à l’utilisateur.
Prerequisites
Pour utiliser l’identité utilisateur de l’agent, vous avez besoin des éléments suivants :
- Modèle d'agent enregistré dans Microsoft Entra ID
- Identité de l’agent créée et liée à l’application de l’agent
- Identité utilisateur de l’agent associée à l’identité de l’agent
Configurer les services utilisateur de l’agent
Le code suivant configure l’identité d’application de l’agent avec des informations d’identification de certificat et inscrit les services requis :
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();
Acquérir des jetons utilisateur avec l’identité de l’agent
Vous pouvez identifier l’utilisateur cible par UPN ou ID d’objet.
Par nom d’utilisateur (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 d’objet utilisateur
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));
});
Mise en cache des jetons avec ClaimsPrincipal
Pour améliorer les performances, mettre en cache les jetons utilisateur en passant une instance ClaimsPrincipal. Le premier appel remplit le principal avec uid et utid assertions ; les appels suivants réutilisent le jeton mis en mémoire 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
Remplacer le locataire
Pour les scénarios multilocataires, vous pouvez remplacer le locataire au moment de l’exécution. Cela est utile lorsque l’application est configurée avec "common" , mais doit cibler un locataire spécifique :
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";
});
});
Examiner un exemple complet d’identité utilisateur de l’agent
La classe suivante fournit des méthodes pour obtenir des profils utilisateur et des en-têtes d’autorisation à l’aide de l’identité utilisateur de l’agent :
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());
}
}
Créer une configuration de service réutilisable
Définir une méthode d’extension
Créez une méthode d’extension réutilisable pour encapsuler la configuration d’identité de l’agent dans votre application :
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();
}
}
Utiliser la méthode d’extension
Appelez la méthode d’extension pour configurer les services dans une seule ligne :
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var serviceProvider = services.ConfigureServicesForAgentIdentities(configuration);
Appeler les API
Cette section montre comment appeler des API à l’aide de chacun des trois modèles d’authentification.
Appeler Microsoft Graph
Les exemples suivants illustrent l’appel de Microsoft Graph en tant que démon standard, un agent autonome et une identité utilisateur de l’agent :
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"));
});
Appeler des API personnalisées avec IDownstreamApi
Utilisez cette option IDownstreamApi pour appeler vos propres API protégées avec l’un des trois modèles d’authentification suivants :
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");
});
Effectuer des appels HTTP manuels
Utilisez IAuthorizationHeaderProvider directement lorsque vous avez besoin d’un contrôle total sur les requêtes 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);
Configurer la mise en cache des jetons
Choisissez une stratégie de mise en cache basée sur votre environnement.
Développement : cache en mémoire
Utilisez la mise en cache en mémoire pour le développement et les tests locaux :
services.AddInMemoryTokenCaches();
Production : Cache distribué
Pour la production, utilisez un cache distribué pour conserver les jetons entre les redémarrages de l’application et les instances de scale-out.
SQL Server
Stockez des jetons dans une table SQL Server :
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = configuration["ConnectionStrings:TokenCache"];
options.SchemaName = "dbo";
options.TableName = "TokenCache";
});
services.AddDistributedTokenCaches();
Redis
Utilisez Redis pour la mise en cache des jetons distribués hautes performances :
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["Redis:ConnectionString"];
options.InstanceName = "TokenCache_";
});
services.AddDistributedTokenCaches();
Cosmos DB
Utilisez Cosmos DB pour la mise en cache des jetons distribués à l’échelle mondiale :
services.AddCosmosDbTokenCaches(options =>
{
options.CosmosDbConnectionString = configuration["CosmosDb:ConnectionString"];
options.DatabaseId = "TokenCache";
options.ContainerId = "Tokens";
});
En savoir plus :Configuration du cache de jetons
Explorer des exemples de Azure
Microsoft fournit des exemples illustrant les modèles d’application démon.
Exemple de référentiel
active-directory-dotnetcore-daemon-v2
Ce référentiel contient plusieurs scénarios :
| Exemple | Description | Lien |
|---|---|---|
| 1-Call-MSGraph | Démon de base appelant Microsoft Graph avec les informations d’identification du client | Afficher l’exemple |
| 2-Call-OwnApi | Démon appelant votre propre API web protégée | Afficher l’exemple |
| 3-Using-KeyVault | Démon utilisant Azure Key Vault pour le stockage de certificats | Afficher l’exemple |
| 4-Multilocataire | Application démon multilocataire | Afficher l’exemple |
| 5-Call-MSGraph-ManagedIdentity | Démon utilisant Managed Identity sur Azure | Afficher l’exemple |
Comparer des exemples de modèles à des modèles de production
Les exemples Azure utilisent TokenAcquirerFactory.GetDefaultInstance() par souci de simplicité : l’approche recommandée pour les applications de console simple, les prototypes et les tests. Ce guide présente les deux modèles :
modèle TokenAcquirerFactory (exemples Azure) :
// Simple, perfect for prototypes and tests
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi("MyApi", ...);
var serviceProvider = tokenAcquirerFactory.Build();
Modèle ServiceCollection complet (applications de production) :
// More control, testable, follows DI best practices
var services = new ServiceCollection();
services.AddTokenAcquisition(true); // true = singleton
services.Configure<MicrosoftIdentityApplicationOptions>(...);
var serviceProvider = services.BuildServiceProvider();
Quand utiliser lequel :
-
Utiliser
TokenAcquirerFactorypour : applications console, prototypes rapides, tests unitaires, services démon simples -
Utiliser
ServiceCollectionpour : applications de production, l'intégration à ASP.NET Core, scénarios DI complexes, services d'arrière-plan avecIHostedService
Les deux approches sont entièrement prises en charge et prêtes pour la production. Choisissez en fonction de la complexité et des besoins d’intégration de votre application.
Résoudre les erreurs courantes
AADSTS700016 : Application introuvable
Cause :ClientId non valide ou l’application n’est pas inscrite dans le tenant.
Solution : Vérifiez que le ClientId dans votre configuration correspond à l'enregistrement de votre application Microsoft Entra.
AADSTS7000215 : clé secrète client non valide
Cause : La clé secrète client est incorrecte, expirée ou non configurée.
Solution:
- Vérifiez que le secret dans Azure portail correspond à votre configuration
- Vérifier la date d’expiration du secret
- Envisagez d’utiliser des certificats pour la production
AADSTS700027 : l’assertion du client contient une signature non valide
Cause : Le certificat introuvable, expiré ou clé privée n’est pas accessible.
Solution:
- Vérifier que le certificat est installé dans le magasin de certificats correct
- Vérifier que le nom unique du certificat correspond à la configuration
- Vérifier que l’application dispose de l’autorisation de lire la clé privée
- Consultez le Guide de configuration des certificats
AADSTS650052 : l’application a besoin d’un accès à un service
Cause : Les autorisations d’API requises ne sont pas accordées ou le consentement administrateur est manquant.
Solution:
- Accédez au portail Azure → inscriptions d'applications → autorisations d’API de votre application →
- Ajouter des autorisations requises (par exemple,
User.Read.Allpour Microsoft Graph) - Cliquez sur le bouton « Accorder le consentement administrateur »
Erreurs d’identité de l’agent
AADSTS50105 : l’utilisateur connecté n’est pas affecté à un rôle
Cause : L’identité de l’agent n’est pas correctement configurée ou n’est pas affectée à l’application.
Solution:
- Vérifier que l’identité de l’agent existe dans Microsoft Entra ID
- Vérifier que l’identité de l’agent est liée à votre application
- Vérifier que l’identité de l’agent dispose des autorisations requises
Jetons acquis mais avec des autorisations incorrectes
Cause : Utilisation de l’identité utilisateur de l’agent, mais demande des autorisations d’application, ou inversement.
Solution:
- Pour les jetons d’application uniquement : utiliser
CreateAuthorizationHeaderForAppAsyncavecWithAgentIdentity - Pour les jetons délégués : utiliser
CreateAuthorizationHeaderForUserAsyncavecWithAgentUserIdentity - S'assurer que les autorisations d'API correspondent au type de jeton (application ou délégué)
Problèmes de mise en cache des jetons
Problème: Les jetons ne sont pas mis en cache, ce qui force une nouvelle acquisition à chaque fois.
Solution:
- Pour l’identité de l’utilisateur de l’agent : réutiliser la même
ClaimsPrincipalinstance entre les appels - Vérifier la connexion de cache distribué (si vous utilisez Redis/SQL)
- Activer la journalisation du débogage pour afficher les opérations de cache
Guide détaillé des diagnostics :journalisation et diagnostics
Contenu connexe
- Appel d’API en aval à partir d’API web - Modèles OBO
- Guide MSAL.NET framework - Cache de jetons et configuration de certificat pour .NET Framework
- configuration Certificate : chargement de certificats à partir de Key Vault, de magasin, de fichier ou de base64
- Configuration du cache de jeton - Stratégies de mise en cache de production
- Journalisation et diagnostics - Résolution des incidents d'acquisition de jetons
- Guide de personnalisation - Modèles de configuration avancés
- documentation de l’application démon Plateforme d'identités Microsoft
- Les exemples Azure : applications de fond
- Package NuGet Microsoft.Identity.Web
- Microsoft.Identity.Abstractions référence de l'API