Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Neste artigo, você criará aplicativos daemon, serviços em segundo plano e agentes autônomos usando Microsoft. Identity.Web. Esses aplicativos são executados sem interação do usuário e autenticados usando identidade de aplicativo (credenciais de cliente) ou identidades de agente.
Entender cenários com suporte
Microsoft. O Identity.Web dá suporte a três tipos de aplicativos não interativos:
| Cenário | Tipo de Autenticação | Tipo de token | Caso de uso |
|---|---|---|---|
| Daemon Padrão | Credenciais do cliente (segredo/certificado) | Token de acesso exclusivo para aplicativo | Serviços em segundo plano, trabalhos agendados, processamento de dados |
| Agente Autônomo | Identidade do agente com credenciais de cliente | Token de acesso somente para aplicativo do agente | Agentes do Copilot, serviços autônomos que agem em nome de uma identidade de um agente. (Normalmente, em uma API Web protegida) |
| Identidade de Usuário do Agente | Identidade do usuário do agente | Identidade do agente usuário com credenciais de cliente | Serviços autônomos atuando em nome de uma identidade de usuário-agente. (Normalmente, em uma API Web protegida) |
Introdução
Pré-requisitos
Antes de começar, verifique se você tem:
- .NET 8.0 ou posterior
- Microsoft Entra registro de aplicativo com credenciais do cliente (segredo do cliente ou certificado)
- Para cenários de agente: identidades de agentes configuradas em seu locatário Microsoft Entra
Instalar pacotes
Adicione os pacotes NuGet necessários ao seu projeto:
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Extensions.Hosting
Escolher uma abordagem de configuração
Microsoft. O Identity.Web fornece duas maneiras de configurar aplicativos daemon:
Opção 1: TokenAcquirerFactory (recomendado para cenários simples)
Melhor para: Protótipos rápidos, aplicativos de console, testes e serviços daemon simples.
O código a seguir cria um TokenAcquirerFactory, configura APIs downstream e Microsoft Graph e chama o API do Graph:
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
// Get the token acquirer factory instance
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
// Configure downstream API and Microsoft Graph (optional)
tokenAcquirerFactory.Services.AddDownstreamApis(
tokenAcquirerFactory.Configuration.GetSection("DownstreamApis"))
.AddMicrosoftGraph();
var serviceProvider = tokenAcquirerFactory.Build();
// Call Microsoft Graph
var graphClient = serviceProvider.GetRequiredService<GraphServiceClient>();
var users = await graphClient.Users.GetAsync();
Vantagens:
- Código clichê mínimo
- Carrega automaticamente
appsettings.json - Perfeito para cenários simples
- Inicialização em uma linha
Desvantagens:
- Não adequado para testes executados em paralelo (singleton)
Opção 2: Coleção de Serviços completa (recomendado para produção)
Melhor para: Aplicativos de produção, cenários complexos, injeção de dependência, testabilidade.
O código a seguir usa o host genérico .NET para configurar a autenticação, a aquisição de token, o cache e um serviço em segundo plano:
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();
Vantagens:
- Controle total sobre provedores de configuração
- Melhor testabilidade com injeção de construtor
- Integra-se ao modelo de hospedagem ASP.NET Core
- Dá suporte a cenários complexos (vários esquemas de autenticação)
- Arquitetura pronta para produção
- Dá suporte à execução de teste paralelo (provedor de serviço isolado por teste)
Observação
O parâmetro true no AddTokenAcquisition(true) significa que o serviço é registrado como um singleton (instância única para o tempo de vida do aplicativo). Use false para o tempo de vida com escopo em aplicativos Web.
Recomendação: Comece com
TokenAcquirerFactoryprotótipos e testes de thread único. Migre para o padrão completoServiceCollectionao criar aplicativos de produção ou executar testes paralelos.
Configurar aplicativos daemon padrão
Os aplicativos daemon padrão são autenticados usando credenciais de cliente (segredo do cliente ou certificado) e obtêm tokens de acesso somente aplicativo para chamar APIs.
Definir configurações de autenticação
Adicione a configuração a seguir ao arquivo appsettings.json . Você pode usar um segredo do cliente ou um certificado (recomendado para produção):
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"ClientCredentials": [
// Option 1: Client Secret
{
"SourceType": "ClientSecret",
"ClientSecret": "your-client-secret",
},
// Option 2: Certificate (recommended for production)
{
"SourceType": "StoreWithDistinguishedName",
"CertificateStorePath": "CurrentUser/My",
"CertificateDistinguishedName": "CN=DaemonAppCert"
}
// More options: https://aka.ms/ms-id-web/client-credentials
]
}
}
Importante: Configure seu appsettings.json para copiar para o diretório de saída. Adicione o seguinte ao arquivo .csproj :
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
ASP.NET Core aplicativos copiam esse arquivo automaticamente, mas aplicativos daemon (e aplicativos OWIN) não.
Definir a configuração do serviço
O código Program.cs a seguir registra opções de identidade da Microsoft, aquisição de token, cache e um serviço hospedado em segundo plano:
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();
Chamar Microsoft Graph
A seguinte classe DaemonWorker.cs usa o SDK do Graph para listar usuários em um agendamento recorrente:
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);
}
}
}
Usar IAuthorizationHeaderProvider
Para obter mais controle sobre chamadas HTTP, use IAuthorizationHeaderProvider para criar cabeçalhos de autorização manualmente:
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;
}
}
Consulte também Chamando APIs downstream para saber mais sobre todas as maneiras que o Microsoft Identity Web propõe chamar APIs downstream.
Configurar agentes autônomos (identidade do agente)
Agentes autônomos utilizam identidades de agentes para adquirir tokens de uso exclusivo para aplicativos. Esse padrão é útil para cenários Copilot e serviços autônomos.
Observação
Microsoft recomenda que os agentes que chamam APIs downstream façam isso de dentro de APIs Web protegidas, mesmo quando os agentes adquirem um token de aplicativo.
Configurar serviços de agente
O código a seguir configura a autenticação, a aquisição de tokens e o suporte à identidade do agente usando a configuração na memória:
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();
Adquirir tokens com a identidade do agente
Depois de configurar os serviços do agente, adquira tokens usando IAuthorizationHeaderProvider ou o SDK do Microsoft Graph:
using Microsoft.Identity.Abstractions;
using Microsoft.Graph;
// Your agent identity GUID
string agentIdentityId = "d84da24a-2ea2-42b8-b5ab-8637ec208024";
// Option 1: Using IAuthorizationHeaderProvider
IAuthorizationHeaderProvider authProvider =
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
var options = new AuthorizationHeaderProviderOptions()
.WithAgentIdentity(agentIdentityId);
string authHeader = await authProvider.CreateAuthorizationHeaderForAppAsync(
scopes: "https://graph.microsoft.com/.default",
options);
// Option 2: Using Microsoft Graph SDK
GraphServiceClient graphClient =
serviceProvider.GetRequiredService<GraphServiceClient>();
var applications = await graphClient.Applications.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(authOptions =>
{
authOptions.WithAgentIdentity(agentIdentityId);
});
});
Examinar um exemplo de agente autônomo completo
A classe a seguir encapsula a aquisição do token de identidade do agente e as chamadas à API do Graph em um serviço reutilizável.
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>();
}
}
Configurar a identidade do usuário do agente
A identidade do usuário do agente permite que os agentes atuem em nome de um usuário agente com permissões delegadas. Use esse padrão para agentes que precisam de sua própria caixa de correio ou outros recursos com escopo de usuário.
Pré-requisitos
Para usar a identidade do usuário do agente, você precisa:
- Modelo do agente registrado no Microsoft Entra ID
- Identidade do agente criada e vinculada ao aplicativo do agente
- Identidade do usuário do agente associada à identidade do agente
Configurar serviços de usuário do agente
O código a seguir configura a identidade do aplicativo do agente com uma credencial de certificado e registra os serviços necessários:
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();
Adquirir tokens de usuário com a identidade do agente
Você pode identificar o usuário de destino por UPN ou ID de objeto.
Por nome de usuário (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));
});
Por ID de objeto do usuário
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));
});
Armazenar tokens em cache com ClaimsPrincipal
Para obter um melhor desempenho, armazene tokens de usuário em cache passando uma instância de ClaimsPrincipal. A primeira chamada popula o principal com as declarações uid e utid; chamadas subsequentes reutilizam o token em cache:
using System.Security.Claims;
using Microsoft.Identity.Abstractions;
// First call - creates cache entry
ClaimsPrincipal userPrincipal = new ClaimsPrincipal();
string authHeader = await authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options,
userPrincipal);
// ClaimsPrincipal now has uid and utid claims for caching
bool hasUserId = userPrincipal.HasClaim(c => c.Type == "uid");
bool hasTenantId = userPrincipal.HasClaim(c => c.Type == "utid");
// Subsequent calls - uses cache
authHeader = await authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options,
userPrincipal); // Reuse the same principal
Substituir o locatário
Para cenários multilocatários, você pode substituir o locatário em tempo de execução. Isso é útil quando o aplicativo está configurado com "common", mas precisa direcionar uma instância específica.
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";
});
});
Examinar um exemplo completo de identidade de usuário de agente
A classe a seguir fornece métodos para obter perfis de usuário e cabeçalhos de autorização usando a identidade do usuário do agente:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Graph;
using Microsoft.Identity.Abstractions;
using System.Security.Claims;
public class AgentUserService
{
private readonly IAuthorizationHeaderProvider _authProvider;
private readonly GraphServiceClient _graphClient;
private readonly string _agentIdentityId;
public AgentUserService(
string agentIdentityId,
IServiceProvider serviceProvider)
{
_agentIdentityId = agentIdentityId;
_authProvider = serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
_graphClient = serviceProvider.GetRequiredService<GraphServiceClient>();
}
public async Task<User> GetUserProfileAsync(string userUpn)
{
var me = await _graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
options.WithAgentUserIdentity(_agentIdentityId, userUpn));
});
return me!;
}
public async Task<User> GetUserProfileByIdAsync(Guid userObjectId)
{
var me = await _graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
options.WithAgentUserIdentity(_agentIdentityId, userObjectId));
});
return me!;
}
public async Task<string> GetAuthHeaderForUserAsync(
string userUpn,
ClaimsPrincipal? cachedPrincipal = null)
{
var options = new AuthorizationHeaderProviderOptions()
.WithAgentUserIdentity(_agentIdentityId, userUpn);
return await _authProvider.CreateAuthorizationHeaderForUserAsync(
scopes: new[] { "https://graph.microsoft.com/.default" },
options,
cachedPrincipal ?? new ClaimsPrincipal());
}
}
Criar configuração de serviço reutilizável
Definir um método de extensão
Crie um método de extensão reutilizável para encapsular a configuração de identidade do agente em seu aplicativo:
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();
}
}
Usar o método de extensão
Chame o método de extensão para configurar serviços em uma única linha:
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var serviceProvider = services.ConfigureServicesForAgentIdentities(configuration);
APIs de chamada
Esta seção mostra como chamar APIs usando cada um dos três padrões de autenticação.
Chamar Microsoft Graph
Os exemplos a seguir demonstram chamar Microsoft Graph como um daemon padrão, um agente autônomo e uma identidade de usuário do agente:
using Microsoft.Graph;
GraphServiceClient graphClient =
serviceProvider.GetRequiredService<GraphServiceClient>();
// Standard daemon (app-only)
var users = await graphClient.Users.GetAsync();
// Autonomous agent (app-only with agent identity)
var apps = await graphClient.Applications.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
{
options.WithAgentIdentity("agent-identity-id");
options.RequestAppToken = true;
});
});
// Agent user identity (delegated with user context)
var me = await graphClient.Me.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(options =>
options.WithAgentUserIdentity("agent-identity-id", "user@tenant.com"));
});
Chamar APIs personalizadas com IDownstreamApi
Use IDownstreamApi para chamar suas próprias APIs protegidas com qualquer um dos três padrões de autenticação:
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");
});
Fazer chamadas HTTP manuais
Use IAuthorizationHeaderProvider diretamente quando precisar de controle total sobre solicitações 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);
Configurar o cache de token
Escolha uma estratégia de cache com base em seu ambiente.
Desenvolvimento: cache na memória
Use o cache na memória para desenvolvimento e teste local:
services.AddInMemoryTokenCaches();
Produção: Cache distribuído
Para produção, use um cache distribuído para persistir tokens entre reinicializações de aplicativo e instâncias de expansão.
SQL Server
Armazene tokens em uma tabela de SQL Server:
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = configuration["ConnectionStrings:TokenCache"];
options.SchemaName = "dbo";
options.TableName = "TokenCache";
});
services.AddDistributedTokenCaches();
Redis
Use o Redis para cache de token distribuído de alto desempenho:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["Redis:ConnectionString"];
options.InstanceName = "TokenCache_";
});
services.AddDistributedTokenCaches();
Cosmos DB
Use o Cosmos DB para cache de token distribuído globalmente:
services.AddCosmosDbTokenCaches(options =>
{
options.CosmosDbConnectionString = configuration["CosmosDb:ConnectionString"];
options.DatabaseId = "TokenCache";
options.ContainerId = "Tokens";
});
Saiba mais:Configuraçãodo cache de token
Explorar exemplos de Azure
Microsoft fornece exemplos que demonstram padrões de aplicativo daemon.
Repositório de exemplo
active-directory-dotnetcore-daemon-v2
Esse repositório contém vários cenários:
| Amostra | Descrição | Link |
|---|---|---|
| 1-Call-MSGraph | Daemon básico chamando Microsoft Graph com credenciais de cliente | Visualizar Exemplo |
| 2-Call-OwnApi | Daemon chamando sua própria API Web protegida | Visualizar Exemplo |
| 3-Using-KeyVault | Daemon usando Azure Key Vault para armazenamento de certificados | Visualizar Exemplo |
| 4-Multi-inquilino | Aplicativo daemon multilocatário | Visualizar Exemplo |
| 5-Call-MSGraph-ManagedIdentity | Daemon usando Identidade Gerenciada no Azure | Visualizar Exemplo |
Comparar padrões de exemplo com padrões de produção
Os exemplos de Azure usam TokenAcquirerFactory.GetDefaultInstance() para simplificar – a abordagem recomendada para aplicativos de console simples, protótipos e testes. Este guia mostra os dois padrões:
Padrão TokenAcquirerFactory (Exemplos do Azure):
// Simple, perfect for prototypes and tests
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi("MyApi", ...);
var serviceProvider = tokenAcquirerFactory.Build();
Padrão Full ServiceCollection (Aplicativos de Produção):
// More control, testable, follows DI best practices
var services = new ServiceCollection();
services.AddTokenAcquisition(true); // true = singleton
services.Configure<MicrosoftIdentityApplicationOptions>(...);
var serviceProvider = services.BuildServiceProvider();
Quando usar qual:
-
Usar
TokenAcquirerFactorypara: Aplicativos de console, protótipos rápidos, testes de unidade, serviços daemon simples -
Use
ServiceCollectionfor: aplicativos de produção, integração ASP.NET Core, cenários de DI complexos, serviços em segundo plano comIHostedService
Ambas as abordagens têm suporte total e estão prontas para produção. Escolha com base nas necessidades de complexidade e integração do aplicativo.
Solucionar erros comuns
AADSTS700016: Aplicativo não encontrado
Causa: Inválido ClientId ou aplicativo não registrado no locatário.
Solution: Verifique se o ClientId em sua configuração corresponde ao registro do aplicativo Microsoft Entra.
Código de erro AADSTS7000215: chave secreta do cliente inválida
Causa: O segredo do cliente está incorreto, expirou ou não está configurado.
Solution:
- Verifique se o segredo no portal Azure corresponde à sua configuração
- Verificar a data de validade do segredo
- Considere usar certificados para produção
AADSTS700027: a asserção do cliente contém assinatura inválida
Causa: Certificado não encontrado, expirado ou chave privada não acessível.
Solution:
- Verificar se o certificado está instalado no repositório de certificados correto
- Verificar se o nome distinto do certificado corresponde à configuração
- Verifique se o aplicativo tem permissão para ler a chave privada
- Consulte o Guia de Configuração de Certificado
AADSTS650052: O aplicativo precisa de acesso a um serviço
Causa: Permissões de API necessárias não concedidas ou consentimento do administrador ausentes.
Solution:
- Navegue até o portal Azure → Registros de aplicativo → Seu aplicativo → Permissões de API
- Adicionar permissões necessárias (por exemplo,
User.Read.Allpara Microsoft Graph) - Clique no botão "Conceder consentimento do administrador"
Erros de identidade do agente
AADSTS50105: O usuário conectado não está atribuído a uma função
Causa: Identidade do agente não configurada corretamente ou não atribuída ao aplicativo.
Solution:
- Verifique se a identidade do agente existe no Microsoft Entra ID
- Verifique se a identidade do agente está vinculada ao seu aplicativo
- Verifique se a identidade do agente tem permissões necessárias
Tokens adquiridos, mas com permissões incorretas
Causa: Usando a identidade do usuário do agente, mas solicitando permissões de aplicativo ou vice-versa.
Solution:
- Para tokens somente de aplicativo: use
CreateAuthorizationHeaderForAppAsynccomWithAgentIdentity - Para tokens delegados: use
CreateAuthorizationHeaderForUserAsynccomWithAgentUserIdentity - Verifique se as permissões de API correspondem ao tipo de token (aplicativo versus delegado)
Problemas de cache de token
Problema: Os tokens não são armazenados em cache, o que força uma nova aquisição a cada vez.
Solution:
- Para a identidade do usuário do agente: reutilize a mesma
ClaimsPrincipalinstância entre chamadas - Verificar a conexão de cache distribuído (se estiver usando o Redis/SQL)
- Habilitar o registro em log de depuração para ver as operações de cache
Diagnósticos detalhados:Guia de Registro em Log e Diagnóstico
Conteúdo relacionado
- Chamando APIs descendentes de APIs da Web – padrões OBO
- Guia do MSAL.NET framework – Cache de token e configuração de certificado para o .NET Framework
- Certificate configuration – Carregando certificados de Key Vault, repositório, arquivo ou Base64
- Configuração de cache de token – Estratégias de armazenamento em cache de produção
- Registro e diagnósticos – Solucionar problemas de aquisição de token
- Guia de personalização – Padrões de configuração avançados
- Documentação de aplicativo daemon da plataforma Microsoft Identity
- Exemplos do Azure: aplicativos daemon
- Pacote NuGet Microsoft.Identity.Web
- Referência da API Microsoft.Identity.Abstractions