Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel erstellen Sie Daemonanwendungen, Hintergrunddienste und autonome Agents mit Microsoft. Identity.Web. Diese Anwendungen werden ohne Benutzerinteraktion ausgeführt und mithilfe von Anwendungsidentitäten (Clientanmeldeinformationen) oder Agentidentitäten authentifiziert.
Verstehen der unterstützten Szenarien
Microsoft. Identity.Web unterstützt drei Arten von nicht interaktiven Anwendungen:
| Szenario | Authentifizierungstyp | Tokentyp | Anwendungsfall |
|---|---|---|---|
| Standarddaemon | Client-Anmeldedaten (Client-Schlüssel/Zertifikat) | Nur-App-Zugriffstoken | Hintergrunddienste, geplante Aufträge, Datenverarbeitung |
| Autonomer Agent | Agentenidentität mit Client-Anmeldeinformationen | Nur-App-Zugriffstoken für Agent | Copilot-Agenten, autonome Dienste, die im Namen einer Agentenidentität agieren. (In der Regel in einer geschützten Web-API) |
| Agent-Benutzeridentität | Agent-Benutzeridentität | Agent-Benutzeridentität mit Client-Anmeldedaten | Autonome Dienste, die im Auftrag einer Agent-Benutzeridentität handeln. (In der Regel in einer geschützten Web-API) |
Beginnen
Voraussetzungen
Bevor Sie beginnen, stellen Sie sicher, dass Sie folgendes haben:
- .NET 8.0 oder höher
- Microsoft Entra App-Registrierung mit client-Anmeldeinformationen (geheimer Clientschlüssel oder Zertifikat)
- Für Agentenszenarien: Agentenidentitäten, die in Ihrem Microsoft Entra-Mandanten konfiguriert sind
Pakete installieren
Fügen Sie dem Projekt die erforderlichen NuGet-Pakete hinzu:
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Extensions.Hosting
Auswählen eines Konfigurationsansatzes
Microsoft. Identity.Web bietet zwei Möglichkeiten zum Konfigurieren von Daemonanwendungen:
Option 1: TokenAcquirerFactory (empfohlen für einfache Szenarien)
Am besten geeignet für: Schnelle Prototypen, Konsolen-Apps, Tests und einfache Daemon-Dienste.
Der folgende Code erstellt eine TokenAcquirerFactory, konfiguriert nachgeschaltete APIs und Microsoft Graph und ruft die Graph-API auf:
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();
Vorteile:
- Minimaler Textbausteincode
- Lädt automatisch
appsettings.json - Perfekt für einfache Szenarien
- Einzeilige Initialisierung
Nachteile:
- Nicht geeignet für das Ausführen von Tests in Parallelbetrieb (Singleton)
Option 2: Full ServiceCollection (empfohlen für die Produktion)
Am besten geeignet für: Produktionsanwendungen, komplexe Szenarien, Abhängigkeitsinjektion, Testbarkeit.
Der folgende Code verwendet den .NET Generic Host zum Konfigurieren der Authentifizierung, des Tokenerwerbs, des Zwischenspeicherns und eines Hintergrunddiensts:
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();
Vorteile:
- Vollzugriff auf Konfigurationsanbieter
- Bessere Testbarkeit mit Konstruktorinjektion
- Integriert sich mit dem ASP.NET Core Hosting-Modell
- Unterstützt komplexe Szenarien (mehrere Authentifizierungsschemas)
- Produktionsfähige Architektur
- Unterstützt parallele Testausführung (isolierter Dienstanbieter pro Test)
Hinweis
Der Parameter true in AddTokenAcquisition(true) bedeutet, dass der Dienst als Singleton registriert wird (einzelne Instanz für die App-Lebensdauer). Verwenden Sie false für eine bereichsbezogene Lebensdauer in Webanwendungen.
Empfehlung: Beginnen Sie mit
TokenAcquirerFactoryPrototypen und Einzelthreadtests. Migrieren Sie zum vollständigenServiceCollectionMuster, wenn Sie Produktionsanwendungen erstellen oder parallele Tests ausführen.
Konfigurieren von Standarddaemonanwendungen
Standarddaemonanwendungen authentifizieren sich mithilfe von Clientanmeldeinformationen (geheimem Clientschlüssel oder Zertifikat) und rufen Nur-App-Zugriffstoken zum Aufrufen von APIs ab.
Konfigurieren von Authentifizierungseinstellungen
Fügen Sie der Datei appsettings.json die folgende Konfiguration hinzu. Sie können entweder einen geheimen Clientschlüssel oder ein Zertifikat verwenden (empfohlen für die Produktion):
{
"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
]
}
}
Wichtig: Stellen Sie Ihr appsettings.json so ein, dass es in das Ausgabeverzeichnis kopiert wird. Fügen Sie Folgendes zu Ihrer .csproj-Datei hinzu:
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
ASP.NET Core Anwendungen kopieren diese Datei automatisch, aber Daemon-Apps (und OWIN-Apps) nicht.
Einrichten der Dienstkonfiguration
Der folgende Program.cs Code registriert Microsoft Identitätsoptionen, Tokenakquisition, Zwischenspeicherung und einen gehosteten Hintergrunddienst:
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();
Microsoft Graph aufrufen
Die folgende DaemonWorker.cs Klasse verwendet das Graph SDK zum Auflisten von Benutzern in einem wiederkehrenden Zeitplan:
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);
}
}
}
Verwenden von IAuthorizationHeaderProvider
Um mehr Kontrolle über HTTP-Aufrufe zu erhalten, verwenden Sie die Verwendung IAuthorizationHeaderProvider zum manuellen Erstellen von Autorisierungsheadern:
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;
}
}
Siehe auch Calling downstream APIs um alle Möglichkeiten zu erfahren, wie Microsoft Identity Web schlägt vor, nachgeschaltete APIs aufzurufen.
Konfigurieren autonomer Agents (Agentidentität)
Autonome Agenten verwenden Agentidentitäten, um App-Only-Token abzurufen. Dieses Muster eignet sich für Copilot Szenarien und autonome Dienste.
Hinweis
Microsoft empfiehlt, dass Agents, die nachgeschaltete APIs aufrufen, dies in geschützten Web-APIs tun, auch wenn die Agents ein App-Token erwerben.
Konfigurieren von Agentdiensten
Der folgende Code richtet die Unterstützung für Authentifizierung, Tokenerfassung und Agentidentität mithilfe der In-Memory-Konfiguration ein:
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();
Abrufen von Token mit Identität des Agents
Nachdem Sie die Agentdienste konfiguriert haben, können Sie Token entweder mit IAuthorizationHeaderProvider oder mithilfe des Microsoft Graph SDK abrufen.
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);
});
});
Überprüfen eines vollständigen autonomen Agent-Beispiels
Die folgende Klasse umschließt den Erwerb von Agentidentitätstoken und Graph-API Aufrufe in einen wiederverwendbaren Dienst:
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>();
}
}
Konfigurieren der Agent-Benutzeridentität
Die Agent-Benutzeridentität ermöglicht Es Agents, im Auftrag eines Agentbenutzers mit delegierten Berechtigungen zu handeln. Verwenden Sie dieses Muster für Agents, die ein eigenes Postfach oder andere ressourcen mit Benutzerbereich benötigen.
Voraussetzungen
Um die Agent-Benutzeridentität zu verwenden, benötigen Sie Folgendes:
- In Microsoft Entra ID registrierter Agent-Blueprint
- Agentidentität erstellt und mit der Agentanwendung verknüpft
- Agent-Benutzeridentität, die der Agentidentität zugeordnet ist
Konfigurieren von Agent-Benutzerdiensten
Der folgende Code konfiguriert die Agentanwendungsidentität mit zertifikatbasierten Anmeldeinformationen und registriert die erforderlichen Dienste:
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();
Benutzertokens mit Agentidentität abrufen
Sie können den Zielbenutzer anhand des UPN oder der Objekt-ID identifizieren.
Nach Benutzername (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));
});
Nach Benutzerobjekt-ID
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));
});
Cachetoken mit ClaimsPrincipal
Um eine bessere Leistung zu erzielen, können Sie Benutzertoken zwischenspeichern, indem Sie eine ClaimsPrincipal Instanz übergeben. Der erste Aufruf befüllt den Principal mit uid und utid Claims. Nachfolgende Aufrufe verwenden erneut das zwischengespeicherte Token.
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
Überschreiben des Mandanten
Für Szenarien mit mehreren Mandanten können Sie den Mandanten zur Laufzeit außer Kraft setzen. Dies ist nützlich, wenn die App mit "common" konfiguriert ist, aber auf einen bestimmten Mandanten ausgerichtet werden muss:
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";
});
});
Überprüfen eines vollständigen Agent-Benutzeridentitätsbeispiels
Die folgende Klasse stellt Methoden zum Abrufen von Benutzerprofilen und Autorisierungsheadern mithilfe der Agent-Benutzeridentität bereit:
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());
}
}
Erstellen einer wiederverwendbaren Dienstkonfiguration
Definieren einer Erweiterungsmethode
Erstellen Sie eine wiederverwendbare Erweiterungsmethode, um die Agentidentitätskonfiguration in Ihrer Anwendung zu kapseln:
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();
}
}
Verwenden Sie die Erweiterungsmethode
Rufen Sie die Erweiterungsmethode auf, um Dienste in einer einzelnen Zeile zu konfigurieren:
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var serviceProvider = services.ConfigureServicesForAgentIdentities(configuration);
Aufrufen von APIs
In diesem Abschnitt wird gezeigt, wie APIs mithilfe der drei Authentifizierungsmuster aufgerufen werden.
Microsoft Graph aufrufen
Die folgenden Beispiele veranschaulichen das Aufrufen von Microsoft Graph als Standarddaemon, einen autonomen Agent und eine Agent-Benutzeridentität:
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"));
});
Aufrufen benutzerdefinierter APIs mit IDownstreamApi
Verwenden Sie IDownstreamApi, um eines der drei Authentifizierungsmuster zu nutzen, um Ihre eigenen geschützten APIs aufzurufen.
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");
});
Manuelle HTTP-Aufrufe durchführen
Verwenden Sie IAuthorizationHeaderProvider direkt, wenn Sie volle Kontrolle über HTTP-Anforderungen benötigen.
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);
Tokenzwischenspeicherung konfigurieren
Wählen Sie eine Zwischenspeicherungsstrategie basierend auf Ihrer Umgebung aus.
Entwicklung: In-Memory-Zwischenspeicher
Verwenden Sie die Speicherzwischenspeicherung für lokale Entwicklung und Tests:
services.AddInMemoryTokenCaches();
Produktion: Verteilter Cache
Verwenden Sie für die Produktion einen verteilten Cache, um Token über App-Neustarts hinweg beizubehalten und das Hochskalieren von Instanzen zu unterstützen.
SQL Server
Speichern von Token in einer SQL Server Tabelle:
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = configuration["ConnectionStrings:TokenCache"];
options.SchemaName = "dbo";
options.TableName = "TokenCache";
});
services.AddDistributedTokenCaches();
Redis
Verwenden Sie Redis für eine leistungsstarke, verteilte Tokenzwischenspeicherung:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["Redis:ConnectionString"];
options.InstanceName = "TokenCache_";
});
services.AddDistributedTokenCaches();
Cosmos DB
Verwenden Sie Cosmos DB für global verteilte Tokenzwischenspeicherung:
services.AddCosmosDbTokenCaches(options =>
{
options.CosmosDbConnectionString = configuration["CosmosDb:ConnectionString"];
options.DatabaseId = "TokenCache";
options.ContainerId = "Tokens";
});
Weitere Informationen:Tokencachekonfiguration
Erkunden Azure Beispiele
Microsoft stellt Beispiele bereit, die Daemon-App-Muster veranschaulichen.
Beispiel-Repository
active-directory-dotnetcore-daemon-v2
Dieses Repository enthält mehrere Szenarien:
| Beispiel | Beschreibung | Verbinden |
|---|---|---|
| 1-Call-MSGraph | Grundlegender Daemon, der Microsoft Graph mit Client-Anmeldeinformationen aufruft | View-Beispiel |
| 2-Call-OwnApi | Daemon aufruft Ihre eigene geschützte Web-API | View-Beispiel |
| 3-Using-KeyVault | Daemon mit Azure Key Vault für den Zertifikatspeicher | View-Beispiel |
| 4-Multi-Tenant | Daemonanwendung mit mehreren Mandanten | View-Beispiel |
| 5-Call-MSGraph-ManagedIdentity | Daemon mit verwalteter Identität auf Azure | View-Beispiel |
Vergleichen von Beispielmustern mit Produktionsmustern
In den Azure Beispielen wird TokenAcquirerFactory.GetDefaultInstance() aus Gründen der Einfachheit verwendet– der empfohlene Ansatz für einfache Konsolenanwendungen, Prototypen und Tests. Diese Anleitung zeigt beide Muster:
TokenAcquirerFactory-Muster (Azure Beispiele):
// Simple, perfect for prototypes and tests
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi("MyApi", ...);
var serviceProvider = tokenAcquirerFactory.Build();
Full ServiceCollection-Muster (Produktions-Apps):
// More control, testable, follows DI best practices
var services = new ServiceCollection();
services.AddTokenAcquisition(true); // true = singleton
services.Configure<MicrosoftIdentityApplicationOptions>(...);
var serviceProvider = services.BuildServiceProvider();
Wann sollte welche verwendet werden:
-
Verwenden Sie
TokenAcquirerFactoryfür: Konsolen-Apps, schnelle Prototypen, Unit-Tests, einfache Daemon-Dienste -
Verwenden Sie
ServiceCollectionfür: Produktionsanwendungen, ASP.NET Core-Integration, komplexe DI-Szenarien, Hintergrunddienste mitIHostedService
Beide Ansätze werden vollständig unterstützt und sind bereit für den Produktionseinsatz. Wählen Sie basierend auf den Komplexitäts- und Integrationsanforderungen Ihrer Anwendung aus.
Häufige Fehler beheben
AADSTS700016: Anwendung nicht gefunden
Ursache: Ungültige ClientId oder nicht im Mandanten registrierte Anwendung.
Solution: Überprüfen Sie, ob die ClientId in Ihrer Konfiguration ihrer Microsoft Entra App-Registrierung entspricht.
AADSTS7000215: Ungültiger geheimer Clientschlüssel
Ursache: Der geheime Clientschlüssel ist falsch, abgelaufen oder nicht konfiguriert.
Lösung:
- Stellen Sie sicher, dass das Geheimnis im Azure-Portal Ihrer Konfiguration entspricht.
- Ablaufdatum des geheimen Schlüssels überprüfen
- Erwägen Sie die Verwendung von Zertifikaten für die Produktion
AADSTS700027: Client assertion enthält ungültige Signatur
Ursache: Zertifikat nicht gefunden, abgelaufen oder privater Schlüssel nicht zugänglich.
Lösung:
- Überprüfen, ob das Zertifikat im richtigen Zertifikatspeicher installiert ist
- Überprüfen, ob der Distinguished Name des Zertifikats mit der Konfiguration übereinstimmt.
- Sicherstellen, dass die Anwendung über die Berechtigung zum Lesen eines privaten Schlüssels verfügt
- Siehe Zertifikatkonfigurationshandbuch
AADSTS650052: Die App benötigt Zugriff auf einen Dienst.
Ursache: Erforderliche API-Berechtigungen fehlen oder die Administratorzustimmung fehlt.
Lösung:
- Navigieren Sie zu Azure-Portal → App-Registrierungen → Ihre App → API-Berechtigungen
- Hinzufügen erforderlicher Berechtigungen (z. B.
User.Read.Allfür Microsoft Graph) - Klicken Sie auf die Schaltfläche "Administratorzustimmung erteilen".
Agentidentitätsfehler
AADSTS50105: Der angemeldete Benutzer ist keiner Rolle zugewiesen.
Ursache: Die Agentidentität ist nicht ordnungsgemäß konfiguriert oder der Anwendung nicht zugewiesen.
Lösung:
- Überprüfen, ob die Agentidentität in Microsoft Entra ID vorhanden ist
- Sicherstellen, dass die Agentidentität mit Ihrer Anwendung verknüpft ist
- Überprüfen, ob die Agentidentität über erforderliche Berechtigungen verfügt
Erworbene Token mit falschen Berechtigungen
Ursache: Verwenden der Agent-Benutzeridentität oder Anfordern von App-Berechtigungen, oder umgekehrt.
Lösung:
- Für Nur-App-Token: Verwenden
CreateAuthorizationHeaderForAppAsyncmitWithAgentIdentity - Für delegierte Token: Verwenden
CreateAuthorizationHeaderForUserAsyncmitWithAgentUserIdentity - Stellen Sie sicher, dass API-Berechtigungen mit dem Tokentyp übereinstimmen (Anwendung im Vergleich zu delegierten)
Probleme beim Zwischenspeichern von Token
Problem: Token werden nicht zwischengespeichert, wodurch jedes Mal eine neue Übernahme erzwungen wird.
Lösung:
- Für die Agent-Benutzeridentität: Dieselbe
ClaimsPrincipal-Instanz bei Aufrufen wiederverwenden - Überprüfen der Verbindung mit verteilten Caches (bei Verwendung von Redis/SQL)
- Aktivieren der Debugprotokollierung zum Anzeigen von Cachevorgängen
Detaillierte Diagnose:Protokollierungs- und Diagnosehandbuch
Verwandte Inhalte
- Aufrufen nachgeschalteter APIs aus Web-APIs – OBO-Muster
- MSAL.NET Frameworkhandbuch – Tokencache- und Zertifikatkonfiguration für .NET Framework
- Certificate-Konfiguration – Laden von Zertifikaten aus Key Vault, Speichern, Datei oder Base64
- Tokencachekonfiguration – Strategien für die Produktionszwischenspeicherung
- Protokollierung und Diagnose – Behandeln von Problemen beim Tokenerwerb
- Anpassungshandbuch – Erweiterte Konfigurationsmuster
- Microsoft-Identitätsplattform Daemon-Anwendung-Dokumentation
- Azure Beispiele: Daemonanwendungen
- Microsoft. Identity.Web NuGet-Paket
- Microsoft. Identity.Abstractions-API-Referenz