Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste artigo, construirás processos em segundo plano, serviços em segundo plano e agentes autónomos usando o Microsoft.Identity.Web. Estas aplicações funcionam sem interação do utilizador e autenticam-se usando a identidade da aplicação (credenciais do cliente) ou as identidades dos agentes.
Compreender cenários suportados
Microsoft. O Identity.Web suporta três tipos de aplicações não interativas:
| Cenário | Tipo de Autenticação | Tipo de Token | Caso de uso |
|---|---|---|---|
| Daemon Padrão | Credenciais do cliente (secreto/certificado) | Token de acesso apenas para aplicação | Serviços de segundo plano, trabalhos agendados, processamento de dados |
| Agente Autónomo | Identidade do agente com credenciais do cliente | Token de acesso apenas para aplicação para agente | Agentes Copilot, serviços autónomos que atuam em nome da identidade de um Agente. (Normalmente numa API Web protegida) |
| Identidade do Utilizador do Agente | Identidade do utilizador do agente | Identidade de utilizador do agente com as credenciais de cliente | Serviços autónomos que atuam em nome da identidade de um utilizador agente. (Normalmente numa API Web protegida) |
Introdução
Pré-requisitos
Antes de começar, certifique-se de que tem:
- .NET 8.0 ou posterior
- Microsoft Entra registo de aplicação com credenciais do cliente (secreto do cliente ou certificado)
- Para cenários de agente: Identidades de agentes configuradas no seu tenant 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
Escolha uma abordagem de configuração
Microsoft. O Identity.Web oferece duas formas de configurar aplicações de daemons:
Opção 1: TokenAcquirerFactory (recomendado para cenários simples)
Melhor para: Protótipos rápidos, aplicações de consola, testes e serviços simples de daemons.
O seguinte código cria um TokenAcquirerFactory, configura APIs subsequentes e o Microsoft Graph, e chama a API do Microsoft 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 padrão mínimo
- Carrega automaticamente
appsettings.json - Perfeito para cenários simples
- Inicialização numa única linha
Desvantagens:
- Não adequado para testes executados em paralelo (singleton)
Opção 2: Full ServiceCollection (recomendada para produção)
Melhor para: Aplicações em produção, cenários complexos, injeção de dependências, teabilidade.
O seguinte código utiliza o Host Genérico .NET para configurar autenticação, aquisição de tokens, 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:
- Controlo total sobre os fornecedores de configuração
- Melhor testabilidade com injeção de construtor
- Integra com o modelo de alojamento ASP.NET Core
- Suporta cenários complexos (múltiplos esquemas de autenticação)
- Arquitetura pronta para produção
- Suporta execução de testes paralelos (fornecedor de serviço isolado por teste)
Observação
O parâmetro true em AddTokenAcquisition(true) significa que o serviço está registado como singleton (uma única instância durante a vida útil da aplicação). Use false para tempo de vida delimitado em aplicações web.
Recomendação: Comece com
TokenAcquirerFactorypara protótipos e testes monothread. Migre para o padrão completoServiceCollectionao construir aplicações de produção ou executar testes paralelos.
Configurar aplicações padrão de daemons
As aplicações padrão de daemons autenticam-se usando credenciais de cliente (secreto do cliente ou certificado) e obtêm tokens de acesso exclusivos da aplicação para chamar APIs.
Configurar definições de autenticação
Adicione a seguinte configuração ao seu ficheiro deappsettings.json . Pode usar um segredo de 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: Defina o appsettings.json para copiar para o diretório de saída. Adicione o seguinte ao seu .csproj ficheiro:
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
As aplicações ASP.NET Core copiam este ficheiro automaticamente, mas as aplicações daemon (e as aplicações OWIN) não.
Configurar a configuração do serviço
O seguinte código Program.cs regista as opções de Identidade da Microsoft, a aquisição de tokens, o armazenamento em cache e um serviço em segundo plano hospedado:
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();
Faça uma chamada ao Microsoft Graph
A seguinte DaemonWorker.cs classe utiliza o Graph SDK para listar utilizadores num calendário 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);
}
}
}
Utilize IAuthorizationHeaderProvider
Para maior controlo sobre chamadas HTTP, use IAuthorizationHeaderProvider para criar manualmente cabeçalhos de autorização:
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 Calling downstream APIs para saber todas as formas Microsoft Identity Web propõe chamar as downstream APIs.
Configurar agentes autónomos (identidade do agente)
Agentes autónomos usam identidades de agentes para obter tokens apenas para aplicações. Este padrão é útil para cenários Copilot e serviços autónomos.
Observação
A Microsoft recomenda que os agentes que chamam APIs downstream o façam a partir de APIs web protegidas, mesmo quando os agentes adquirem um token de aplicação.
Configurar serviços de agente
O seguinte código configura autenticação, aquisição de tokens e suporte à identidade do agente usando configuração em 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 de agente
Após configurar os serviços do agente, adquira tokens usando IAuthorizationHeaderProvider ou o SDK Microsoft Graph:
using Microsoft.Identity.Abstractions;
using Microsoft.Graph;
// Your agent identity GUID
string agentIdentityId = "d84da24a-2ea2-42b8-b5ab-8637ec208024";
// Option 1: Using IAuthorizationHeaderProvider
IAuthorizationHeaderProvider authProvider =
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
var options = new AuthorizationHeaderProviderOptions()
.WithAgentIdentity(agentIdentityId);
string authHeader = await authProvider.CreateAuthorizationHeaderForAppAsync(
scopes: "https://graph.microsoft.com/.default",
options);
// Option 2: Using Microsoft Graph SDK
GraphServiceClient graphClient =
serviceProvider.GetRequiredService<GraphServiceClient>();
var applications = await graphClient.Applications.GetAsync(request =>
{
request.Options.WithAuthenticationOptions(authOptions =>
{
authOptions.WithAgentIdentity(agentIdentityId);
});
});
Revise um exemplo completo de agente autónomo
A seguinte classe integra a aquisição de token de identidade de agente e as chamadas Graph API num 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 utilizador do agente
A identidade do utilizador do agente permite que os agentes atuem em nome de um utilizador do agente com permissões delegadas. Use este padrão para agentes que necessitem da sua própria caixa de correio ou de outros recursos com âmbito de utilizador.
Pré-requisitos
Para usar a identidade do utilizador agente, precisa de:
- "Blueprint de agente registado no Microsoft Entra ID"
- Identidade do agente criada e ligada à aplicação do agente
- Identidade do utilizador do agente associada à identidade do agente
Configurar serviços de utilizador agente
O seguinte código configura a identidade da aplicação do agente com uma credencial de certificado e regista 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 identidade de agente
Pode identificar o utilizador-alvo pelo UPN ou pelo ID do objeto.
Por nome de utilizador (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 utilizador
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));
});
Cache de tokens com "ClaimsPrincipal"
Para melhor desempenho, armazene em cache tokens de utilizador passando uma instância ClaimsPrincipal. A primeira chamada preenche um principal com as reivindicações uid e utid; chamadas subsequentes reutilizam o token armazenado 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
Anular o inquilino
Para cenários multi-inquilino, podes sobrepor o tenant em tempo de execução. Isto é útil quando a aplicação está configurada com "common", mas precisa direcionar um inquilino específico.
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";
});
});
Revise um exemplo completo de identidade de utilizador de agente
A seguinte classe fornece métodos para obter perfis de utilizador e cabeçalhos de autorização usando a identidade do utilizador 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
Defina um método de extensão
Crie um método de extensão reutilizável para encapsular a configuração da identidade do agente em toda a sua aplicação:
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();
}
}
Utilizar o método de extensão
Chame o método de extensão para configurar serviços numa única linha:
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var serviceProvider = services.ConfigureServicesForAgentIdentities(configuration);
APIs de chamadas
Esta secção mostra como chamar APIs usando cada um dos três padrões de autenticação.
Faça uma chamada ao Microsoft Graph
Os exemplos seguintes demonstram como chamar o Microsoft Graph como um daemon padrão, um agente autónomo e uma identidade de utilizador 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"));
});
Invocar APIs personalizadas com IDownstreamApi
Use IDownstreamApi para chamar as 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");
});
Faça chamadas HTTP manuais
Use IAuthorizationHeaderProvider diretamente quando precisar de controlo total sobre os pedidos 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 cache de tokens
Escolha uma estratégia de cache baseada no seu ambiente.
Desenvolvimento: Cache em memória
Use cache em memória para desenvolvimento e testes locais:
services.AddInMemoryTokenCaches();
Produção: Cache distribuída
Para produção, use uma cache distribuída para persistir tokens através de reinicios de aplicações e instâncias de scale-out.
SQL Server
Armazene tokens numa tabela 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 tokens distribuídos e de alto desempenho:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["Redis:ConnectionString"];
options.InstanceName = "TokenCache_";
});
services.AddDistributedTokenCaches();
Cosmos DB
Utilize o Cosmos DB para caching global distribuído de tokens.
services.AddCosmosDbTokenCaches(options =>
{
options.CosmosDbConnectionString = configuration["CosmosDb:ConnectionString"];
options.DatabaseId = "TokenCache";
options.ContainerId = "Tokens";
});
Saiba mais:Configuração da Cache do Token
Explore exemplos do Azure
A Microsoft fornece exemplos que demonstram padrões de aplicações daemon.
Repositório de exemplo
active-directory-dotnetcore-daemon-v2
Este repositório contém múltiplos cenários:
| Exemplo | Descrição | Link |
|---|---|---|
| 1-Call-MSGraph | Daemon básico que chama o Microsoft Graph com credenciais do cliente | Ver Exemplo |
| 2-Call-OwnApi | Daemon que chama a sua própria API web protegida | Ver Exemplo |
| 3-Using-KeyVault | Daemon que utiliza o Azure Key Vault para armazenamento de certificados | Ver Exemplo |
| 4-Multi-Inquilino | Aplicação de daemon multiusuário | Ver Exemplo |
| 5-Call-MSGraph-Managed Identity | Daemon usando Identidade Gerida no Azure | Ver Exemplo |
Compare padrões de amostra com padrões de produção
Os Azure exemplos usam TokenAcquirerFactory.GetDefaultInstance() para simplificar — a abordagem recomendada para aplicações simples de consola, protótipos e testes. Este guia mostra ambos os padrões:
Padrão da Fábrica de Aquisição de Tokens (Amostras do Azure):
// Simple, perfect for prototypes and tests
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi("MyApi", ...);
var serviceProvider = tokenAcquirerFactory.Build();
Padrão Full ServiceCollection (Aplicações 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:
-
Utilização
TokenAcquirerFactorypara: Aplicações de consola, protótipos rápidos, testes unitários, serviços simples de demónios -
Use
ServiceCollectionpara: aplicações de produção, integração ASP.NET Core, cenários complexos de DI, serviços em segundo plano comIHostedService
Ambas as abordagens são totalmente suportadas e prontas para produção. Escolha com base na complexidade e nas necessidades de integração da sua aplicação.
Solucionar erros comuns
AADSTS700016: Aplicação não encontrada
Causa: Inválido ClientId ou aplicação não registada no locatário.
Solução: Verifique se o ClientId na sua configuração corresponde ao registo da sua Microsoft Entra app.
AADSTS7000215: Segredo inválido do cliente
Causa: O segredo do cliente está incorreto, expirado ou não está configurado.
Solution:
- Verifique se o segredo no portal do Azure corresponde à sua configuração
- Verifique a data de expiração secreta
- 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 que o certificado está instalado no armazenamento correto de certificados
- Verificar se o nome distinto do certificado corresponde à configuração
- Garantir que a aplicação tem permissão para ler a chave privada
- Consulte o Guia de Configuração de Certificados
AADSTS650052: A aplicação precisa de acesso a um serviço
Causa: Permissões necessárias da API não concedidas ou consentimento do administrador em falta.
Solution:
- Navegue até o Portal Azure → Registo de Aplicações → A sua aplicação → Permissões da 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 utilizador com sessão iniciada não tem um papel atribuído
Causa: Identidade do agente não devidamente configurada ou não atribuída à aplicação.
Solution:
- Verificar a existência da identidade do agente no Microsoft Entra ID
- Assegure que a identidade do agente está associada à sua candidatura
- Verifique se a identidade do agente tem permissões necessárias
Tokens adquiridos mas com permissões erradas
Causa: Usar a identidade do utilizador do agente mas pedir permissões para a aplicação, ou vice-versa.
Solution:
- Para tokens apenas para aplicações: Usar
CreateAuthorizationHeaderForAppAsynccomWithAgentIdentity - Para tokens delegados: Usar
CreateAuthorizationHeaderForUserAsynccomWithAgentUserIdentity - Garantir que as permissões da API correspondem ao tipo de token (aplicação vs. delegado)
Problemas de cache de tokens
Problema: Os tokens não são armazenados em cache, o que obriga a uma nova aquisição a cada vez.
Solution:
- Para a identidade do utilizador agente: Reutilizar a mesma
ClaimsPrincipalinstância entre chamadas - Verificar a ligação à cache distribuída (se estiver a usar Redis/SQL)
- Habilitar a depuração de logs para ver as operações de cache
Diagnóstico detalhado:Guia de Registo e Diagnóstico
Conteúdo relacionado
- Chamar APIs a jusante a partir de APIs web - padrões OBO
- Guia MSAL.NET framework - Cache de tokens e configuração de certificados para .NET Framework
- Configuração de certificados - Carregamento de certificados de Key Vault, armazenamento, ficheiro ou Base64
- Configuração da cache de tokens - Estratégias de cache em produção
- Registo e diagnóstico - Resolução de problemas na aquisição de tokens
- Guia de personalização - Padrões de configuração avançados
- Documentação de aplicações daemon da plataforma de identidade Microsoft
- Azure Exemplos: aplicações de demónios
- Microsoft. Pacote NuGet da Identity.Web
- Referência da API Microsoft.Identity.Abstractions