Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam artikel ini, Anda membangun aplikasi daemon, layanan latar belakang, dan agen otonom menggunakan Microsoft. Identity.Web. Aplikasi ini berjalan tanpa interaksi pengguna dan mengautentikasi menggunakan identitas aplikasi (kredensial klien) atau identitas agen.
Memahami skenario yang didukung
Microsoft. Identity.Web mendukung tiga jenis aplikasi non-interaktif:
| Skenario | Jenis Autentikasi | Jenis Token | Kasus Penggunaan |
|---|---|---|---|
| Daemon Standar | Kredensial klien (rahasia/sertifikat) | Token akses khusus aplikasi | Layanan latar belakang, pekerjaan terjadwal, pemrosesan data |
| Agen Otonom | Identitas agen dengan kredensial klien | Token akses khusus aplikasi untuk agen | Agen copilot, layanan otonom yang bertindak atas nama identitas agen. (Biasanya dalam API Web yang dilindungi) |
| Identitas Pengguna Agen | Identitas agen pengguna | Identitas pengguna agen dengan kredensial klien | Layanan otonom yang bertindak atas nama identitas Pengguna Agen. (Biasanya dalam API Web yang dilindungi) |
Memulai
Prasyarat
Sebelum mulai, pastikan bahwa Anda memiliki:
- .NET 8.0 atau yang lebih baru
- Pendaftaran aplikasi Microsoft Entra dengan kredensial klien (rahasia klien atau sertifikat)
- Dalam skenario agen: Identitas agen yang dikonfigurasi di tenant Microsoft Entra Anda
Memasang paket
Tambahkan paket NuGet yang diperlukan ke proyek Anda:
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Extensions.Hosting
Memilih pendekatan konfigurasi
Microsoft. Identity.Web menyediakan dua cara untuk mengonfigurasi aplikasi daemon:
Opsi 1: TokenAcquirerFactory (direkomendasikan untuk skenario sederhana)
Terbaik untuk: Prototipe cepat, aplikasi konsol, pengujian, dan layanan daemon sederhana.
Kode berikut membuat TokenAcquirerFactory, mengonfigurasi API hilir dan Microsoft Graph, dan memanggil 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();
Keuntungan:
- Boilerplate code yang minimal
- Memuat secara otomatis
appsettings.json - Sempurna untuk skenario sederhana
- Inisialisasi dalam satu baris
Kekurangan:
- Tidak cocok untuk pengujian yang berjalan secara paralel (singleton)
Opsi 2: Full ServiceCollection (disarankan untuk produksi)
Terbaik untuk: Aplikasi produksi, skenario kompleks, injeksi dependensi, kemampuan uji coba.
Kode berikut menggunakan Host Generik .NET untuk mengonfigurasi autentikasi, perolehan token, penyimpanan sementara, dan layanan latar belakang.
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();
Keuntungan:
- Kontrol penuh atas penyedia konfigurasi
- Uji coba yang lebih baik dengan injeksi konstruktor
- Terintegrasi dengan model hosting ASP.NET Core
- Mendukung skenario kompleks (beberapa skema autentikasi)
- Arsitektur siap produksi
- Mendukung eksekusi pengujian paralel (penyedia layanan terisolasi per pengujian)
Nota
Parameter true di AddTokenAcquisition(true) berarti layanan terdaftar sebagai singleton (satu instance untuk masa pakai aplikasi). Gunakan false untuk masa pakai terlingkup dalam aplikasi web.
Rekomendasi: Mulailah dengan
TokenAcquirerFactoryuntuk prototipe dan pengujian utas tunggal. Migrasikan ke pola penuhServiceCollectionsaat membangun aplikasi produksi atau menjalankan pengujian paralel.
Mengonfigurasi aplikasi daemon standar
Aplikasi daemon standar mengautentikasi menggunakan kredensial klien (rahasia klien atau sertifikat) dan mendapatkan token akses khusus aplikasi untuk memanggil API.
Konfigurasikan pengaturan otentikasi
Tambahkan konfigurasi berikut ke file appsettings.json Anda. Anda dapat menggunakan rahasia klien atau sertifikat (disarankan untuk produksi):
{
"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
]
}
}
Penting: Atur appsettings.json Anda untuk menyalin ke direktori output. Tambahkan yang berikut ini ke file Anda .csproj :
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
ASP.NET Core aplikasi menyalin file ini secara otomatis, tetapi aplikasi daemon (dan aplikasi OWIN) tidak.
Menyiapkan konfigurasi layanan
Kode Program.cs berikut mendaftarkan opsi identitas Microsoft, perolehan token, cache, dan layanan latar belakang yang dihosting.
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();
Memanggil Microsoft Graph
Kelas DaemonWorker.cs berikut menggunakan Graph SDK untuk mencantumkan pengguna pada jadwal berulang:
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);
}
}
}
Gunakan IAuthorizationHeaderProvider
Untuk kontrol lebih lanjut atas panggilan HTTP, gunakan IAuthorizationHeaderProvider untuk membuat header otorisasi secara manual:
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;
}
}
Lihat juga Caling API hilir untuk mempelajari semua cara Microsoft Identity Web mengusulkan untuk memanggil API hilir.
Mengonfigurasi agen otonom (identitas agen)
Agen otonom menggunakan identitas agen untuk mendapatkan token khusus aplikasi. Pola ini berguna untuk skenario Copilot dan layanan otonom.
Nota
Microsoft menyarankan agar agen yang memanggil API hilir melakukannya dari dalam API web yang dilindungi, bahkan ketika agen memperoleh token aplikasi.
Mengonfigurasi layanan agen
Kode berikut menyiapkan autentikasi, akuisisi token, dan dukungan identitas agen menggunakan konfigurasi dalam memori:
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();
Memperoleh token dengan identitas agen
Setelah mengonfigurasi layanan agen, dapatkan token menggunakan IAuthorizationHeaderProvider atau 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);
});
});
Meninjau contoh agen otonom lengkap
Kelas berikut membungkus akuisisi token identitas agen dan panggilan Graph API ke dalam layanan yang dapat digunakan kembali:
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>();
}
}
Mengonfigurasi identitas pengguna agen
Identitas pengguna agen memungkinkan agen untuk bertindak atas nama pengguna agen dengan izin yang didelegasikan. Gunakan pola ini untuk agen yang memerlukan kotak surat mereka sendiri atau sumber daya cakupan pengguna lainnya.
Prasyarat
Untuk menggunakan identitas pengguna agen, Anda memerlukan:
- Cetak biru agen terdaftar di Microsoft Entra ID
- Identitas agen dibuat dan ditautkan ke aplikasi agen
- Identitas pengguna agen yang terkait dengan identitas agen
Mengonfigurasi layanan pengguna agen
Kode berikut mengonfigurasi identitas aplikasi agen dengan kredensial sertifikat dan mendaftarkan layanan yang diperlukan:
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();
Memperoleh token pengguna dengan identitas agen
Anda dapat mengidentifikasi pengguna target berdasarkan UPN atau ID objek.
Menurut nama pengguna (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));
});
Menurut ID Objek pengguna
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));
});
Menyimpan Sementara Token dengan ClaimsPrincipal
Untuk meningkatkan performa, simpan sementara token pengguna dengan mengoper instans ClaimsPrincipal. Panggilan pertama mengisi identitas pengguna dengan klaim uid dan utid, sedangkan panggilan berikutnya menggunakan kembali token yang di-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
Mengambil alih penyewa
Untuk skenario multi-tenant, Anda dapat menggantikan tenant saat runtime. Ini berguna ketika aplikasi dikonfigurasi dengan "common" tetapi perlu menargetkan penyewa tertentu:
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";
});
});
Meninjau contoh identitas pengguna agen lengkap
Kelas berikut menyediakan metode untuk mendapatkan profil pengguna dan header otorisasi menggunakan identitas pengguna agen:
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());
}
}
Membuat konfigurasi layanan yang dapat digunakan kembali
Menentukan metode ekstensi
Buat metode ekstensi yang dapat digunakan kembali untuk merangkum konfigurasi identitas agen di seluruh aplikasi Anda:
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();
}
}
Menggunakan metode ekstensi
Panggil metode ekstensi untuk mengonfigurasi layanan dalam satu baris:
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var serviceProvider = services.ConfigureServicesForAgentIdentities(configuration);
Panggil API
Bagian ini menunjukkan cara memanggil API menggunakan masing-masing dari tiga pola autentikasi.
Memanggil Microsoft Graph
Contoh berikut menunjukkan panggilan Microsoft Graph sebagai daemon standar, agen otonom, dan identitas pengguna agen:
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"));
});
Memanggil API kustom dengan IDownstreamApi
Gunakan IDownstreamApi untuk memanggil API yang dilindungi Anda sendiri dengan salah satu dari tiga pola autentikasi:
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");
});
Melakukan panggilan HTTP manual
Gunakan IAuthorizationHeaderProvider secara langsung saat Anda memerlukan kontrol penuh atas permintaan 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);
Konfigurasi cache token
Pilih strategi penyimpanan sementara berdasarkan lingkungan Anda.
Pengembangan: Cache dalam memori
Gunakan caching in-memory untuk pengembangan dan pengujian lokal:
services.AddInMemoryTokenCaches();
Produksi: Cache terdistribusi
Untuk produksi, gunakan cache terdistribusi untuk mempertahankan token di seluruh mulai ulang aplikasi dan instans peluasan skala.
SQL Server
Simpan token dalam tabel SQL Server:
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = configuration["ConnectionStrings:TokenCache"];
options.SchemaName = "dbo";
options.TableName = "TokenCache";
});
services.AddDistributedTokenCaches();
Redis
Gunakan Redis untuk penyimpanan cache token berkinerja tinggi dan terdistribusi.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration["Redis:ConnectionString"];
options.InstanceName = "TokenCache_";
});
services.AddDistributedTokenCaches();
Cosmos DB
Gunakan Cosmos DB untuk caching token yang terdistribusi secara global.
services.AddCosmosDbTokenCaches(options =>
{
options.CosmosDbConnectionString = configuration["CosmosDb:ConnectionString"];
options.DatabaseId = "TokenCache";
options.ContainerId = "Tokens";
});
Pelajari lebih lanjut:Konfigurasi Cache Token
Menjelajahi contoh Azure
Microsoft menyediakan sampel yang menunjukkan pola aplikasi daemon.
Repositori sampel
active-directory-dotnetcore-daemon-v2
Repositori ini berisi beberapa skenario:
| Sample | Deskripsi | Link |
|---|---|---|
| 1-Call-MSGraph | Panggilan daemon dasar Microsoft Graph dengan kredensial klien | Lihat Sampel |
| 2-Call-OwnApi | Daemon memanggil API web anda sendiri yang dilindungi | Lihat Sampel |
| 3-Using-KeyVault | Daemon menggunakan Azure Key Vault untuk penyimpanan sertifikat | Lihat Sampel |
| 4-Multi-Tenant | Aplikasi daemon multi-tenant | Lihat Sampel |
| 5-Call-MSGraph-ManagedIdentity | Daemon menggunakan Identitas Terkelola di Azure | Lihat Sampel |
Membandingkan pola sampel dengan pola produksi
Sampel Azure menggunakan
pola TokenAcquirerFactory (Sampel Azure):
// Simple, perfect for prototypes and tests
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.AddDownstreamApi("MyApi", ...);
var serviceProvider = tokenAcquirerFactory.Build();
Pola ServiceCollection Lengkap (Aplikasi untuk Produksi):
// More control, testable, follows DI best practices
var services = new ServiceCollection();
services.AddTokenAcquisition(true); // true = singleton
services.Configure<MicrosoftIdentityApplicationOptions>(...);
var serviceProvider = services.BuildServiceProvider();
Kapan menggunakan yang:
-
Menggunakan
TokenAcquirerFactoryuntuk: Aplikasi konsol, prototipe cepat, pengujian unit, layanan daemon sederhana -
Gunakan
ServiceCollectionuntuk: Aplikasi produksi, integrasi ASP.NET Core, skenario DI kompleks, layanan latar belakang denganIHostedService
Kedua pendekatan didukung penuh dan siap produksi. Pilih berdasarkan kompleksitas aplikasi dan kebutuhan integrasi Anda.
Memecahkan masalah kesalahan umum
AADSTS700016: Aplikasi tidak ditemukan
Menyebabkan: Tidak valid ClientId atau aplikasi tidak terdaftar di penyewa.
Solution: Verifikasi ClientId dalam konfigurasi Anda cocok dengan pendaftaran aplikasi Microsoft Entra Anda.
AADSTS7000215: Rahasia klien tidak valid
Menyebabkan: Rahasia klien salah, kedaluwarsa, atau tidak dikonfigurasi.
Solution:
- Verifikasi rahasia di portal Azure sesuai dengan konfigurasi Anda
- Periksa tanggal kedaluwarsa rahasia
- Pertimbangkan untuk menggunakan sertifikat untuk produksi
AADSTS700027: Pernyataan klien berisi tanda tangan yang tidak valid
Menyebabkan: Sertifikat tidak ditemukan, kedaluwarsa, atau kunci privat tidak dapat diakses.
Solution:
- Verifikasi sertifikat diinstal di penyimpanan sertifikat yang benar
- Periksa nama pembeda sertifikat cocok dengan konfigurasi
- Pastikan aplikasi memiliki izin untuk membaca kunci privat
- Lihat Panduan Konfigurasi Sertifikat
AADSTS650052: Aplikasi memerlukan akses ke layanan
Menyebabkan: Izin API yang diperlukan tidak diberikan atau persetujuan admin hilang.
Solution:
- Navigasi ke portal Azure → Pendaftaran aplikasi → izin API → aplikasi Anda
- Tambahkan izin yang diperlukan (misalnya,
User.Read.Alluntuk Microsoft Graph) - Klik tombol "Berikan persetujuan admin"
Kesalahan identitas agen
AADSTS50105: Pengguna yang masuk tidak memiliki peran yang ditetapkan
Menyebabkan: Identitas agen tidak dikonfigurasi dengan benar atau tidak ditetapkan ke aplikasi.
Solution:
- Verifikasi keberadaan identitas agen di Microsoft Entra ID
- Pastikan identitas agen ditautkan ke aplikasi Anda
- Periksa apakah identitas agen memiliki izin yang diperlukan
Token diperoleh tetapi dengan izin yang salah
Menyebabkan: Menggunakan identitas pengguna agen tetapi meminta izin aplikasi, atau sebaliknya.
Solution:
- Untuk token khusus aplikasi: Gunakan
CreateAuthorizationHeaderForAppAsyncdenganWithAgentIdentity - Untuk token yang didelegasikan: Gunakan
CreateAuthorizationHeaderForUserAsyncdenganWithAgentUserIdentity - Pastikan izin API cocok dengan jenis token (aplikasi vs. didelegasikan)
Masalah penembolokan token
Masalah: Token tidak di-cache, yang memaksa akuisisi baru setiap kali.
Solution:
- Untuk identitas pengguna agen: Gunakan kembali instans yang sama
ClaimsPrincipaldi seluruh panggilan - Memverifikasi koneksi cache terdistribusi (jika menggunakan Redis/SQL)
- Mengaktifkan pengelogan debug untuk melihat operasi cache
Diagnostik terperinci:Panduan Pencatatan dan Diagnostik
Konten terkait
- Memanggil API hilir dari API web - pola OBO
- panduan kerangka kerja MSAL.NET - Cache token dan konfigurasi sertifikat untuk .NET Framework
- Konfigurasi Sertifikat - Memuat sertifikat dari Key Vault, penyimpanan, berkas, atau Base64
- Konfigurasi cache token - Strategi caching produksi
- Pengelogan dan diagnostik - Memecahkan masalah akuisisi token
- Panduan kustomisasi - Pola konfigurasi tingkat lanjut
- dokumentasi platform identitas Microsoft untuk aplikasi daemon
- Contoh Azure: aplikasi daemon
- Microsoft.Identity.Web Paket NuGet
- Referensi API Microsoft.Identity.Abstractions