Daemon-toepassingen en agentidentiteiten bouwen met Microsoft. Identity.Web

In dit artikel bouwt u daemon-toepassingen, achtergrondservices en autonome agents met behulp van Microsoft. Identity.Web. Deze toepassingen worden uitgevoerd zonder tussenkomst van de gebruiker en verifiëren met behulp van toepassingsidentiteiten (clientreferenties) of agentidentiteiten.

Ondersteunde scenario's begrijpen

Microsoft. Identity.Web ondersteunt drie typen niet-interactieve toepassingen:

Scenario Authenticatietype Tokentype Gebruikssituatie
Standaard daemon Clientreferenties (geheim/certificaat) Alleen-app-toegangstoken Achtergrondservices, geplande taken, gegevensverwerking
Autonome agent Agentidentiteit met clientreferenties Alleen-app-toegangstoken voor agent Copilot agenten, autonome diensten die handelen namens een agentidentiteit. (Meestal in een beveiligde web-API)
Gebruikersidentiteit van agent Gebruikersidentiteit van agent Gebruikersidentiteit van agent met clientinloggegevens Autonome services die optreden namens een gebruikersidentiteit van een Agent. (Meestal in een beveiligde web-API)

Aan de slag gaan

Vereiste voorwaarden

Zorg ervoor dat u voordat u begint de volgende zaken paraat hebt:

  • .NET 8.0 of hoger
  • Microsoft Entra app-registratie met clientreferenties (clientgeheim of certificaat)
  • Voor agentscenario's: Agentidentiteiten die zijn geconfigureerd in uw Microsoft Entra-tenant

Pakketten installeren

Voeg de vereiste NuGet-pakketten toe aan uw project:

dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Extensions.Hosting

Een configuratiebenadering kiezen

Microsoft. Identity.Web biedt twee manieren om daemon-toepassingen te configureren:

Geschikt voor: Snelle prototypen, console-apps, testen en eenvoudige daemon-services.

Met de volgende code maakt u een TokenAcquirerFactory, configureert u downstream-API's en Microsoft Graph en roept u de Graph API aan:

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();

Voordelen:

  • Minimale standaardcode
  • Laadt automatisch appsettings.json
  • Perfect voor eenvoudige scenario's
  • Initialisatie met één regel

Nadelen:

  • Niet geschikt voor tests die parallel worden uitgevoerd (singleton)

Geschikt voor: Productietoepassingen, complexe scenario's, afhankelijkheidsinjectie, testbaarheid.

De volgende code maakt gebruik van de .NET Generic Host voor het configureren van verificatie, tokenverwerving, caching en een achtergrondservice:

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();

Voordelen:

  • Volledige controle over configuratieproviders
  • Betere testbaarheid met constructorinjectie
  • Integreert met ASP.NET Core hostingmodel
  • Ondersteunt complexe scenario's (meerdere verificatieschema's)
  • Architectuur die gereed is voor productie
  • Ondersteunt parallelle testuitvoering (geïsoleerde serviceprovider per test)

Opmerking

De parameter true in AddTokenAcquisition(true) betekent dat de service is geregistreerd als een singleton (één uitvoering voor de looptijd van de app). Gebruik false voor scope-gebaseerde levensduur in webapplicaties.

Aanbeveling: Begin met TokenAcquirerFactory prototypen en tests met één thread. Migreer naar het volledige ServiceCollection patroon bij het bouwen van productietoepassingen of het uitvoeren van parallelle tests.


Standaard daemontoepassingen configureren

Standaard daemon-toepassingen verifiëren met behulp van clientreferentiebewijzen (clientgeheim of certificaat) en verkrijgen alleen-app toegangstokens om API's aan te roepen.

Verificatie-instellingen configureren

Voeg de volgende configuratie toe aan uw appsettings.json-bestand . U kunt een clientgeheim of een certificaat gebruiken (aanbevolen voor productie):

{
  "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
    ]
  }
}

Belangrijk: Stel uw appsettings.json in om te kopiëren naar de uitvoermap. Voeg het volgende toe aan uw .csproj bestand:

<ItemGroup>
  <None Update="appsettings.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

ASP.NET Core toepassingen dit bestand automatisch kopiëren, maar daemon-apps (en OWIN-apps) niet.

Serviceconfiguratie instellen

De volgende Program.cs code registreert Microsoft identiteitsopties, tokenverwerving, caching en een gehoste achtergrondservice:

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 aanroepen

In de volgende DaemonWorker.cs-klasse wordt de Graph SDK gebruikt om gebruikers weer te geven volgens een terugkerend schema:

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);
        }
    }
}

IAuthorizationHeaderProvider gebruiken

Gebruik dit voor meer controle over HTTP-aanroepen IAuthorizationHeaderProvider om handmatig autorisatieheaders te maken:

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;
    }
}

Zie ook Downstream-API's aanroepen voor meer informatie over alle manieren waarop Microsoft Identity Web downstream-API's aanroept.


Autonome agents configureren (agentidentiteit)

Autonome agents gebruiken agentidentiteiten om alleen-app-tokens te verkrijgen. Dit patroon is handig voor Copilot scenario's en autonome services.

Opmerking

Microsoft raadt aan dat agents die downstream-API's aanroepen dit doen vanuit beveiligde web-API's, zelfs wanneer de agents een app-token verkrijgen.

Agentservices configureren

Met de volgende code stelt u verificatie, tokenverwerving en agentidentiteitsondersteuning in met behulp van configuratie in het geheugen:

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();

Tokens verkrijgen met agentidentiteit

Nadat u agentservices hebt geconfigureerd, verwerft u tokens met behulp van IAuthorizationHeaderProvider of de 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);
    });
});

Bekijk een volledig voorbeeld van een autonome agent

De volgende klasse verpakt het ophalen van agentidentiteitstokens en Graph API aanroepen naar een herbruikbare service:

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>();
    }
}

Gebruikersidentiteit van agent configureren

Met de gebruikersidentiteit van de agent kunnen agents handelen namens een agentgebruiker met gedelegeerde machtigingen. Gebruik dit patroon voor agents die hun eigen postvak of andere resources met gebruikersbereik nodig hebben.

Vereiste voorwaarden

Als u de gebruikersidentiteit van de agent wilt gebruiken, hebt u het volgende nodig:

  • Agent blauwdruk die is geregistreerd in Microsoft Entra ID
  • Agentidentiteit gemaakt en gekoppeld aan de agenttoepassing
  • Agentgebruikersidentiteit geassocieerd met de agentidentiteit

Agentgebruikersservices configureren

Met de volgende code configureert u de identiteit van de agenttoepassing met een certificaatreferentie en registreert u de vereiste services:

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();

Gebruikerstokens verkrijgen met agentidentiteit

U kunt de doelgebruiker identificeren op UPN of object-id.

Op gebruikersnaam (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));
});

Per gebruikersobject-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));
});

Cachetokens met ClaimsPrincipal

Voor betere prestaties kunt u gebruikerstokens cachen door een ClaimsPrincipal-exemplaar door te geven. De eerste aanroep vult de principal met uid en utid claims; volgende aanroepen gebruiken het token in de cache opnieuw:

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

De tenant overschrijven

Voor scenario's met meerdere tenants kunt u de tenant tijdens runtime overschrijven. Dit is handig wanneer de app is geconfigureerd met "common" maar moet zijn gericht op een specifieke tenant:

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";
    });
});

Een volledig voorbeeld van een gebruikersidentiteit van een agent bekijken

De volgende klasse biedt methoden voor het ophalen van gebruikersprofielen en autorisatieheaders met behulp van de gebruikersidentiteit van de 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());
    }
}

Herbruikbare serviceconfiguratie maken

Een extensiemethode definiëren

Maak een herbruikbare extensiemethode voor het inkapselen van agentidentiteitsconfiguratie in uw toepassing:

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();
    }
}

De extensiemethode gebruiken

Roep de extensiemethode aan om services op één regel te configureren:

var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .Build();

var serviceProvider = services.ConfigureServicesForAgentIdentities(configuration);

API's aanroepen

In deze sectie wordt beschreven hoe u API's aanroept met behulp van elk van de drie verificatiepatronen.

Microsoft Graph aanroepen

In de volgende voorbeelden ziet u hoe u Microsoft Graph aanroept als een standaard daemon, een autonome agent en een gebruikersidentiteit van een 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"));
});

Aangepaste API's aanroepen met IDownstreamApi

Gebruik IDownstreamApi dit om uw eigen beveiligde API's aan te roepen met een van de drie verificatiepatronen:

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");
    });

Handmatige HTTP-aanroepen uitvoeren

Rechtstreeks gebruiken IAuthorizationHeaderProvider wanneer u volledige controle over HTTP-aanvragen nodig hebt:

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);

Tokencaching configureren

Kies een cachestrategie op basis van uw omgeving.

Ontwikkeling: Cache in het geheugen

Cache in het geheugen gebruiken voor lokale ontwikkeling en testen:

services.AddInMemoryTokenCaches();

Productie: Gedistribueerde cache

Voor productie gebruikt u een gedistribueerde cache om tokens bij het opnieuw opstarten en uitschalen van apps vast te houden.

SQL Server

Tokens opslaan in een SQL Server tabel:

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = configuration["ConnectionStrings:TokenCache"];
    options.SchemaName = "dbo";
    options.TableName = "TokenCache";
});
services.AddDistributedTokenCaches();

Redis

Redis gebruiken voor high-performance gedistribueerde tokencaching:

services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = configuration["Redis:ConnectionString"];
    options.InstanceName = "TokenCache_";
});
services.AddDistributedTokenCaches();

Cosmos DB

Cosmos DB gebruiken voor wereldwijd gedistribueerde tokencaching:

services.AddCosmosDbTokenCaches(options =>
{
    options.CosmosDbConnectionString = configuration["CosmosDb:ConnectionString"];
    options.DatabaseId = "TokenCache";
    options.ContainerId = "Tokens";
});

Meer informatie:Token-cacheconfiguratie


Voorbeelden van Azure verkennen

Microsoft bevat voorbeelden die daemon-app-patronen demonstreren.

Voorbeeldopslagplaats

active-directory-dotnetcore-daemon-v2

Deze opslagplaats bevat meerdere scenario's:

Voorbeeld Beschrijving Verbinden
1-Call-MSGraph Eenvoudige daemon die Microsoft Graph aanroept met clientreferenties Voorbeeld weergeven
2-Call-OwnApi Daemon die uw eigen beveiligde web-API aanroept Voorbeeld weergeven
3-Using-KeyVault Daemon die gebruikmaakt van Azure Key Vault voor certificaatopslag Voorbeeld weergeven
4-Multitenant Daemon-toepassing met meerdere tenants Voorbeeld weergeven
5-Call-MSGraph-ManagedIdentity Daemon met beheerde identiteit op Azure Voorbeeld weergeven

Voorbeeldpatronen vergelijken met productiepatronen

De Azure voorbeelden maken gebruik van TokenAcquirerFactory.GetDefaultInstance() om het eenvoudig te maken: de aanbevolen benadering voor simple-console-apps, prototypes en tests. In deze handleiding worden beide patronen weergegeven:

TokenAcquirerFactory Pattern (Azure Samples):

// Simple, perfect for prototypes and tests
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi("MyApi", ...);
var serviceProvider = tokenAcquirerFactory.Build();

Full ServiceCollection patroon (productie-apps):

// More control, testable, follows DI best practices
var services = new ServiceCollection();
services.AddTokenAcquisition(true); // true = singleton
services.Configure<MicrosoftIdentityApplicationOptions>(...);
var serviceProvider = services.BuildServiceProvider();

Wanneer gebruik je welke:

  • Gebruiken TokenAcquirerFactory voor: Console-apps, snelle prototypes, eenheidstests, eenvoudige daemon-services
  • Gebruik ServiceCollection voor: Productietoepassingen, ASP.NET Core integratie, complexe DI-scenario's, achtergrondservices met IHostedService

Beide benaderingen worden volledig ondersteund en gereed voor productie. Kies op basis van de complexiteit en integratiebehoeften van uw toepassing.


Veelvoorkomende fouten oplossen

AADSTS700016: De toepassing is niet gevonden

Oorzaak: Ongeldig ClientId of de toepassing is niet geregistreerd in de tenant.

Solution: Controleer of de ClientId in uw configuratie overeenkomt met de registratie van uw Microsoft Entra-app.

AADSTS7000215: ongeldig clientgeheim

Oorzaak: Clientgeheim is onjuist, verlopen of niet geconfigureerd.

Solution:

  • Controleer of het geheim in Azure portal overeenkomt met uw configuratie
  • Vervaldatum van geheim controleren
  • Overweeg het gebruik van certificaten voor productie

AADSTS700027: Clientverklaring bevat ongeldige handtekening

Oorzaak: Het certificaat is niet gevonden, verlopen of persoonlijke sleutel is niet toegankelijk.

Solution:

  • Controleren of het certificaat is geïnstalleerd in het juiste certificaatarchief
  • Controleren of de DN-naam van het certificaat overeenkomt met de configuratie
  • Zorg ervoor dat de toepassing gemachtigd is om een persoonlijke sleutel te lezen
  • Raadpleeg de handleiding voor certificaatconfiguratie

AADSTS650052: De app heeft toegang nodig tot een service

Oorzaak: Vereiste API-machtigingen zijn niet verleend of beheerderstoestemming ontbreekt.

Solution:

  1. Ga naar Azure portal → App-registraties → Uw app → API-machtigingen
  2. Vereiste machtigingen toevoegen (bijvoorbeeld User.Read.All voor Microsoft Graph)
  3. Klik op de knop Beheerderstoestemming verlenen

Agentidentiteitsfouten

AADSTS50105: De aangemelde gebruiker is niet toegewezen aan een rol

Oorzaak: Agentidentiteit is niet juist geconfigureerd of niet toegewezen aan de toepassing.

Solution:

  • Controleer of de agentidentiteit bestaat in Microsoft Entra ID
  • Controleren of de agent-identiteit is gekoppeld aan uw toepassing
  • Controleer of de agentidentiteit vereiste machtigingen heeft

Tokens verkregen, maar met verkeerde machtigingen

Oorzaak: Gebruikersidentiteit van agent gebruiken, maar app-machtigingen aanvragen, of omgekeerd.

Solution:

  • Voor alleen-app-tokens: Gebruiken CreateAuthorizationHeaderForAppAsync met WithAgentIdentity
  • Voor gedelegeerde tokens: Gebruiken CreateAuthorizationHeaderForUserAsync met WithAgentUserIdentity
  • Zorg ervoor dat API-machtigingen overeenkomen met het tokentype (toepassing versus gedelegeerd)

Problemen met het opslaan van tokens in cache

Probleem: Tokens worden niet in de cache opgeslagen, waardoor elke keer een nieuwe aankoop wordt afgedwongen.

Solution:

  • Voor de gebruikersidentiteit van de agent: hetzelfde ClaimsPrincipal exemplaar opnieuw gebruiken voor aanroepen
  • Gedistribueerde cacheverbinding controleren (als u Redis/SQL gebruikt)
  • Logboekregistratie voor foutopsporing inschakelen om cachebewerkingen te bekijken

Gedetailleerde diagnostische gegevens:Handleiding voor logboekregistratie en diagnostische gegevens