Vytváření aplikací démona a identit agentů pomocí Microsoft Identity.Web

V tomto článku vytvoříte aplikace démona, služby na pozadí a autonomní agenty pomocí Microsoft. Identity.Web. Tyto aplikace běží bez zásahu uživatele a ověřují se pomocí identity aplikace (přihlašovacích údajů klienta) nebo identit agentů.

Vysvětlení podporovaných scénářů

Microsoft. Identity.Web podporuje tři typy neinteraktivních aplikací:

Scénář Typ ověření Typ tokenu Případ použití
Standardní démon Přihlašovací údaje klienta (tajný klíč nebo certifikát) Přístupový token jen pro aplikaci Služby na pozadí, naplánované úlohy, zpracování dat
Autonomní agent Identita agenta s přihlašovacími údaji klienta Přístupový token jen pro aplikaci pro agenta Copilot agenty, autonomní služby působící jménem agentní identity. (Obvykle v chráněném webovém rozhraní API)
Identita uživatele agenta Identita uživatele agenta Identita uživatele agenta s přihlašovacími údaji klienta Autonomní služby, které fungují jako zástupce identity uživatele Agenta. (Obvykle v chráněném webovém rozhraní API)

Začínáme

Předpoklady

Než začnete, ujistěte se, že máte:

  • .NET 8.0 nebo novější
  • Registrace aplikace Microsoft Entra pomocí přihlašovacích údajů klienta klienta (tajný klíč klienta nebo certifikát)
  • Scénáře pro agenty: Identity agentů nakonfigurované ve vašem Microsoft Entra tenantovi

Instalace balíčků

Přidejte do projektu požadované balíčky NuGet:

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

Volba přístupu ke konfiguraci

Microsoft. Identity.Web nabízí dva způsoby konfigurace aplikací démona:

Nejvhodnější pro: Rychlé prototypy, konzolové aplikace, testování a jednoduché služby.

Následující kód vytvoří TokenAcquirerFactory, nakonfiguruje podřízená rozhraní API a Microsoft Graph a zavolá Graph API:

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

Výhody:

  • Minimální šablonový kód
  • Automaticky se načte appsettings.json
  • Ideální pro jednoduché scénáře
  • Inicializace s jedním řádkem

Nevýhody:

  • Není vhodné pro testy spuštěné paralelně (singleton)

Nejvhodnější pro: Produkční aplikace, složité scénáře, injektáž závislostí, testovatelnost.

Následující kód používá .NET obecného hostitele ke konfiguraci ověřování, získávání tokenů, ukládání do mezipaměti a služby na pozadí:

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

Výhody:

  • Úplná kontrola nad poskytovateli konfigurace
  • Lepší testovatelnost pomocí injektáže konstruktoru
  • Integrace s modelem hostování ASP.NET Core
  • Podporuje složité scénáře (více schémat ověřování)
  • Architektura připravená pro produkční prostředí
  • Podporuje paralelní spouštění testů (izolovaný poskytovatel služeb na test)

Poznámka:

Parametr trueAddTokenAcquisition(true) znamená, že služba je zaregistrovaná jako singleton (jedna instance po celou dobu života aplikace). Používá se false pro vymezenou dobu života ve webových aplikacích.

Doporučení: Začněte s TokenAcquirerFactory pro prototypy a jednovláknové testy. Migrace na úplný ServiceCollection vzor při sestavování produkčních aplikací nebo spouštění paralelních testů


Konfigurace standardních démonových aplikací

Standardní aplikace démona se ověřují pomocí přihlašovacích údajů klienta (tajný klíč klienta nebo certifikátu) a získávají přístupové tokeny jen pro aplikace pro volání rozhraní API.

Konfigurace nastavení ověřování

Do souboruappsettings.json přidejte následující konfiguraci. Můžete použít tajný klíč klienta nebo certifikát (doporučeno pro produkční prostředí):

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

Důležité: Nastavte svůj appsettings.json k kopírování do výstupního adresáře. Přidejte následující do souboru .csproj.

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

ASP.NET Core aplikace tento soubor zkopírují automaticky, ale aplikace démona (a aplikace OWIN) ne.

Nastavení konfigurace služby

Následující kód Program.cs registruje možnosti Microsoft Identity, získání tokenu, ukládání do mezipaměti a hostované služby na pozadí:

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

Zavolejte Microsoft Graph

Následující DaemonWorker.cs třída používá sadu Graph SDK k výpisu uživatelů podle plánu opakování:

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

Použití IAuthorizationHeaderProvider

Pokud chcete mít větší kontrolu nad voláními HTTP, použijte IAuthorizationHeaderProvider k ručnímu vytvoření autorizačních hlaviček:

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

Viz také Volání podřízených rozhraní API, abyste se dozvěděli o všech způsobech, které Microsoft Identity Web navrhuje pro volání podřízených rozhraní API.


Konfigurace autonomních agentů (identita agenta)

Autonomní agenti používají identifikátory agentů k získání tokenů jen pro aplikace. Tento model je užitečný pro Copilot scénáře a autonomní služby.

Poznámka:

Microsoft doporučuje, aby agenti volající podřízená rozhraní API to udělali z chráněných webových rozhraní API, i když agenti získávají token aplikace.

Konfigurace služeb agenta

Následující kód nastaví podporu ověřování, získání tokenu a identity agenta pomocí konfigurace v paměti:

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

Získání tokenů pomocí identity agenta

Po konfiguraci služeb agenta získejte tokeny pomocí IAuthorizationHeaderProvider nebo sady 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);
    });
});

Přehled kompletního příkladu autonomního agenta

Následující třída obaluje proces získání tokenu identity agenta a volání Graph API do služby, kterou lze znovu použít.

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

Konfigurace identity uživatele agenta

Identita uživatele agenta umožňuje agentům jednat jménem uživatele agenta s delegovanými oprávněními. Tento vzor použijte pro agenty, kteří potřebují vlastní poštovní schránku nebo jiné prostředky s oborem uživatele.

Předpoklady

Pokud chcete použít identitu uživatele agenta, potřebujete:

  • Plán agenta zaregistrovaný v Microsoft Entra ID
  • Identita agenta vytvořená a propojená s aplikací agenta
  • Identita uživatele agenta přidružená k identitě agenta

Konfigurace uživatelských služeb agenta

Následující kód nakonfiguruje identitu aplikace agenta s přihlašovacími údaji certifikátu a zaregistruje požadované služby:

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

Získání tokenů uživatele pomocí identity agenta

Cílového uživatele můžete identifikovat podle hlavního názvu uživatele (UPN) nebo ID objektu.

Podle uživatelského jména (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));
});

Podle ID objektu uživatele

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

Tokeny mezipaměti s ClaimsPrincipal

Pro lepší výkon ukládejte tokeny uživatelů do mezipaměti pomocí instance ClaimsPrincipal. První volání naplní hlavní objekt s uid a utid nároky; následná volání znovu používají token uložený v mezipaměti:

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

Přepsat nájemce

V případě multi-tenantních scénářů můžete tenanta nahradit za běhu programu. To je užitečné, když je aplikace nakonfigurovaná s "common", ale potřebuje cílit na konkrétního nájemce:

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

Kontrola kompletního příkladu identity uživatele agenta

Následující třída poskytuje metody pro získání profilů uživatelů a autorizačních hlaviček pomocí identity uživatele agenta:

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

Vytvoření opakovaně použitelné konfigurace služby

Definování metody rozšíření

Vytvořte opakovaně použitelnou metodu rozšíření pro zapouzdření konfigurace identity agenta napříč vaší aplikací:

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

Použití metody rozšíření

Voláním metody rozšíření nakonfigurujte služby na jednom řádku:

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

var serviceProvider = services.ConfigureServicesForAgentIdentities(configuration);

Volání rozhraní API

Tato část ukazuje, jak volat rozhraní API pomocí každého ze tří vzorů ověřování.

Zavolejte Microsoft Graph

Následující příklady ukazují volání Microsoft Graph jako standardního démona, autonomního agenta a identity uživatele agenta:

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

Volání vlastních rozhraní API pomocí IDownstreamApi

Můžete IDownstreamApi volat vlastní chráněná rozhraní API s libovolnými třemi vzory ověřování:

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

Provádění ručních volání HTTP

Přímo použijte IAuthorizationHeaderProvider , když potřebujete úplnou kontrolu nad požadavky 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);

Konfigurace ukládání tokenů do mezipaměti

Zvolte strategii ukládání do mezipaměti na základě vašeho prostředí.

Vývoj: Mezipaměť v paměti

Používejte ukládání do paměti RAM pro místní vývoj a testování.

services.AddInMemoryTokenCaches();

Produkční prostředí: Distribuovaná mezipaměť

V produkčním prostředí používejte distribuovanou mezipaměť k zachování tokenů napříč restartováními aplikace a instancemi horizontálního navýšení kapacity.

SQL Server

Ukládání tokenů v tabulce SQL Server:

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

Redis

Použití Redisu pro vysoce výkonné ukládání distribuovaných tokenů do mezipaměti:

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

Cosmos DB

Použití Cosmos DB pro ukládání globálně distribuovaných tokenů do mezipaměti:

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

Další informace:Konfigurace mezipaměti tokenů


Prozkoumání ukázek Azure

Microsoft poskytuje ukázky, které demonstrují vzory démonických aplikací.

Ukázkové úložiště

active-directory-dotnetcore-daemon-v2

Toto úložiště obsahuje několik scénářů:

Ukázka Description Odkaz
1-Call-MSGraph Jednoduché volání služby Microsoft Graph s využitím přihlašovacích údajů klienta Zobrazit ukázku
2-Call-OwnApi Démon volání vlastního chráněného webového rozhraní API Zobrazit ukázku
3-Using-KeyVault Démon využívající Azure Key Vault pro úložiště certifikátů Zobrazit ukázku
4-Multi-Tenant Aplikace démona s více tenanty Zobrazit ukázku
5-Call-MSGraph-ManagedIdentity Démon s využitím spravované identity ve službě Azure Zobrazit ukázku

Porovnání ukázkových vzorů s produkčními vzory

Ukázky Azure používají pro zjednodušení—doporučený postup pro jednoduché konzolové aplikace, prototypy a testy . Tato příručka ukazuje oba vzory:

TokenAcquirerFactory Pattern (Ukázky Azure):

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

Vzor Full ServiceCollection (produkční aplikace):

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

Kdy použít:

  • Použít TokenAcquirerFactory pro: Konzolové aplikace, rychlé prototypy, jednotkové testy, jednoduché daemon služby
  • Použití ServiceCollection pro: produkční aplikace, integrace ASP.NET Core, složité scénáře DI, služby na pozadí s IHostedService

Oba přístupy jsou plně podporované a připravené pro produkční prostředí. Vyberte si na základě složitosti a potřeb integrace vaší aplikace.


Řešení běžných chyb

AADSTS700016: Aplikace nebyla nalezena.

Příčina: Neplatný ClientId nebo aplikace není zaregistrována v uživatelském účtu.

Solution: Ověřte, že ClientId v konfiguraci odpovídá vaší registraci aplikace Microsoft Entra.

AADSTS7000215: Neplatný tajný klíč klienta

Příčina: Tajný klíč klienta je nesprávný, vypršela jeho platnost nebo není nakonfigurovaný.

Solution:

  • Ověřte, že tajný kód na portálu Azure odpovídá vaší konfiguraci.
  • Kontrola data vypršení platnosti tajného kódu
  • Zvažte použití certifikátů pro produkční prostředí.

AADSTS700027: Tvrzení klienta obsahuje neplatný podpis.

Příčina: Certifikát nebyl nalezen, vypršela jeho platnost, nebo není přístupný privátní klíč.

Solution:

  • Ověření, že je certifikát nainstalovaný ve správném úložišti certifikátů
  • Kontrola, zda se rozlišující název certifikátu shoduje s konfigurací
  • Ujistěte se, že aplikace má oprávnění ke čtení privátního klíče.
  • Viz Průvodce konfigurací certifikátu

AADSTS650052: Aplikace potřebuje přístup ke službě.

Příčina: Požadovaná oprávnění rozhraní API nebyla udělena nebo chybí souhlas správce.

Solution:

  1. Přejděte na portál Azure → Registrace aplikací → Vaše aplikace → Oprávnění rozhraní API
  2. Přidání požadovaných oprávnění (např. User.Read.All pro Microsoft Graph)
  3. Klikněte na tlačítko Udělit souhlas správce.

Chyby identity agenta

AADSTS50105: Přihlášený uživatel není přiřazen k roli.

Příčina: Identita agenta není správně nakonfigurovaná nebo není přiřazena k aplikaci.

Solution:

  • Ověřte, zda agentova identita existuje v Microsoft Entra ID
  • Ujistěte se, že je identita agenta propojená s vaší aplikací.
  • Kontrola, že identita agenta má požadovaná oprávnění

Tokeny získané, ale s nesprávnými oprávněními

Příčina: Použití identity uživatele agenta při žádosti o oprávnění aplikace nebo naopak.

Solution:

  • Pro tokeny jen pro aplikace: Používá se CreateAuthorizationHeaderForAppAsync s WithAgentIdentity
  • Pro delegované tokeny: Použijte CreateAuthorizationHeaderForUserAsync s WithAgentUserIdentity
  • Ujistěte se, že oprávnění rozhraní API odpovídají typu tokenu (aplikace vs. delegovaná).

Problémy s ukládáním tokenů do mezipaměti

Problém: Tokeny nejsou ukládány do mezipaměti, což vyžaduje jejich nové získání při každém požadavku.

Solution:

  • Pro opakované použití identity uživatele agenta: Použijte stejnou instanci ClaimsPrincipal napříč voláními
  • Ověření připojení distribuované mezipaměti (pokud používáte Redis nebo SQL)
  • Povolit zaznamenávání ladění pro zobrazení operací mezipaměti

Podrobná diagnostika:Průvodce protokolováním a diagnostikou