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.
Cache token meningkatkan performa aplikasi, keandalan, dan pengalaman pengguna. Microsoft.Identity.Web menyediakan strategi penembolokan fleksibel yang menyeimbangkan performa, persistensi, dan keandalan operasional.
Ikhtisar
Bagian ini menjelaskan token mana yang disimpan sementara oleh Microsoft.Identity.Web dan mengapa penyimpanan sementara penting untuk aplikasi Anda.
Token apa yang di-cache?
Microsoft. Identity.Web menyimpan beberapa jenis token:
| Jenis Token | Ukuran | Ruang lingkup | Penggusuran |
|---|---|---|---|
| Token Akses | ~2 KB | Per (pengguna/aplikasi, penyewa, sumber daya) | Otomatis (berbasis seumur hidup) |
| Refresh Token | Variabel | Per akun pengguna | Berbasis manual atau kebijakan |
| Token Identifikasi | ~2-7 KB | Per pengguna | Otomatis |
Tempat penembolokan token berlaku:
- API panggilan aplikasi web - Token pengguna untuk akses yang didelegasikan
- API Web memanggil API tujuan - token OBO (memerlukan kebijakan penghapusan yang cermat)
- Aplikasi Daemon - Token hanya untuk aplikasi pada panggilan antar layanan
Mengapa token cache?
Keuntungan Performa:
- Mengurangi perjalanan pulang pergi ke Microsoft Entra ID
- Panggilan API yang lebih cepat (L1: <10ms vs L2: ~30ms vs jaringan: >100ms)
- Latensi yang lebih rendah untuk pengguna akhir
Manfaat Keandalan:
- Terus bekerja selama pemadaman Microsoft Entra sementara
- Tahan terhadap gangguan jaringan sementara
- Degradasi yang anggun saat cache terdistribusi gagal
Keuntungan Biaya:
- Mengurangi permintaan autentikasi (menghindari pembatasan)
- Biaya Azure yang lebih rendah untuk operasi autentikasi
Mulai Cepat
Mulai dengan cepat menggunakan salah satu konfigurasi cache berikut, tergantung pada lingkungan Anda.
Pengembangan - Cache dalam Memori
Contoh berikut menambahkan cache token dalam memori, cocok untuk pengembangan dan sampel:
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
Keuntungan:
- Pengaturan sederhana
- Performa cepat
- Tidak ada dependensi eksternal
Kekurangan:
- Cache hilang saat menghidupkan ulang aplikasi. Di aplikasi web, pengguna tetap masuk melalui cookie tetapi harus masuk kembali untuk mendapatkan token akses dan mengisi ulang cache
- Tidak cocok untuk implementasi produksi multi-server
- Tidak dibagikan di seluruh instans aplikasi
Produksi - cache terdistribusi
Untuk aplikasi produksi, terutama penyebaran multi-server, gunakan cache terdistribusi yang didukung oleh Redis atau penyedia lain:
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
// Choose your cache implementation
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("Redis");
options.InstanceName = "MyApp_";
});
Keuntungan:
- Bertahan setelah aplikasi dihidupkan ulang
- Dibagikan di semua instance aplikasi
- Cache L1+L2 otomatis
Kekurangan:
- Memerlukan infrastruktur cache eksternal
- Kompleksitas konfigurasi tambahan
- Latensi jaringan untuk operasi cache
Memilih strategi cache
Gunakan diagram alur keputusan dan matriks berikut untuk memilih strategi cache yang paling sesuai dengan penyebaran Anda.
flowchart TD
Start([Token Caching<br/>Decision]) --> Q1{Production<br/>Environment?}
Q1 -->|No - Dev/Test| DevChoice[In-Memory Cache<br/>AddInMemoryTokenCaches]
Q1 -->|Yes| Q2{Multiple Server<br/>Instances?}
Q2 -->|No - Single Server| Q3{App Restarts<br/>Acceptable?}
Q3 -->|Yes| DevChoice
Q3 -->|No| DistChoice
Q2 -->|Yes| DistChoice[Distributed Cache<br/>AddDistributedTokenCaches]
DistChoice --> Q4{Cache<br/>Implementation?}
Q4 -->|High Performance| Redis[Redis Cache<br/>StackExchange.Redis<br/>⭐ Recommended]
Q4 -->|Azure Native| Azure[Azure Cache for Redis,<br/>Azure Cosmos DB,<br/>or Azure Database for PostgreSQL]
Q4 -->|On-Premises| SQL[SQL Server Cache<br/>AddDistributedSqlServerCache]
Q4 -->|Testing| DistMem[Distributed Memory<br/>Not for production]
Redis --> L1L2[Automatic L1+L2<br/>Caching]
Azure --> L1L2
SQL --> L1L2
DistMem --> L1L2
L1L2 --> Config[Configure Options<br/>MsalDistributedTokenCacheAdapterOptions]
DevChoice --> MemConfig[Configure Memory Options<br/>MsalMemoryTokenCacheOptions]
style Start fill:#e1f5ff
style DevChoice fill:#d4edda
style DistChoice fill:#fff3cd
style Redis fill:#d1ecf1
style L1L2 fill:#f8d7da
Matriks keputusan
Tabel berikut ini meringkas jenis cache yang direkomendasikan untuk skenario penyebaran umum.
| Skenario | Cache yang Direkomendasikan | Alasan |
|---|---|---|
| Pengembangan lokal | In-Memory | Kesederhanaan, tidak ada infrastruktur yang diperlukan |
| Sampel/demo | In-Memory | Penyiapan mudah untuk demonstrasi |
| Produksi server tunggal (mulai ulang OK) | In-Memory | Dapat diterima jika sesi dapat dibuat ulang |
| Produksi multi-server | Redis | Cache bersama, performa tinggi, andal |
| aplikasi yang dihosting Azure | Azure Cache for Redis | Integrasi Azure asli, layanan terkelola |
| Perusahaan lokal | SQL Server | Memanfaatkan infrastruktur yang ada |
| Lingkungan PostgreSQL | PostgreSQL | Menggunakan database PostgreSQL yang ada, semantik SQL yang sudah dikenal |
| Lingkungan keamanan tinggi | SQL Server + Enkripsi | Residensi data, enkripsi saat tidak aktif |
| Menguji skenario terdistribusi | Memori Terdistribusi | Menguji perilaku cache L2 tanpa infrastruktur |
Implementasi cache
Microsoft. Identity.Web mendukung beberapa implementasi cache. Pilih salah satu yang cocok dengan persyaratan infrastruktur dan ketersediaan Anda.
Cache dalam memori
Kapan menggunakan:
- Pengembangan dan pengujian
- Penyebaran server tunggal dengan perilaku hidupkan ulang yang dapat diterima
- Sampel dan prototipe
Configuration:
Kode berikut mendaftarkan cache token dalam memori dengan pengaturan default:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
Dengan opsi kustom:
Anda dapat menyesuaikan batas kedaluwarsa dan ukuran dengan menentukan opsi:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches(options =>
{
// Token cache entry will expire after this duration
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);
// Limit cache size (default is unlimited)
options.SizeLimit = 500 * 1024 * 1024; // 500 MB
});
→ Pelajari selengkapnya tentang konfigurasi cache dalam memori
Cache terdistribusi (L2) dengan dukungan L1 otomatis
Kapan menggunakan:
- Penyebaran multi-server lingkungan produksi
- Aplikasi yang memerlukan persistensi cache saat restart
- Skenario ketersediaan tinggi
Fitur utama: Sejak Microsoft.Identity.Web v1.8.0, cache terdistribusi secara otomatis menyertakan cache L1 dalam memori untuk meningkatkan performa dan keandalan.
Redis Cache (direkomendasikan)
Tambahkan string koneksi Redis ke appsettings.json:
{
"ConnectionStrings": {
"Redis": "localhost:6379"
}
}
Kemudian daftarkan cache token terdistribusi dan penyedia Redis di Program.cs:
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.Distributed;
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
// Redis cache implementation
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("Redis");
options.InstanceName = "MyApp_"; // Unique prefix per application
});
// Optional: Configure distributed cache behavior
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
// Control L1 cache size
options.L1CacheOptions.SizeLimit = 500 * 1024 * 1024; // 500 MB
// Handle L2 cache failures gracefully
options.OnL2CacheFailure = (exception) =>
{
if (exception is StackExchange.Redis.RedisConnectionException)
{
// Log the failure
// Optionally attempt reconnection
return true; // Retry the operation
}
return false; // Don't retry
};
});
Azure Cache for Redis
Untuk menggunakan Azure Cache for Redis, daftarkan cache dengan Azure string koneksi Anda:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("AzureRedis");
options.InstanceName = "MyApp_";
});
Format string koneksi:
<cache-name>.redis.cache.windows.net:6380,password=<access-key>,ssl=True,abortConnect=False
SQL Server tembolok
Contoh berikut mengonfigurasi SQL Server sebagai backend cache terdistribusi:
builder.Services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString("TokenCacheDb");
options.SchemaName = "dbo";
options.TableName = "TokenCache";
// Set expiration longer than access token lifetime (default 1 hour)
// This prevents cache entries from expiring before tokens
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
Cache Azure Cosmos DB
Contoh berikut mengonfigurasi Azure Cosmos DB sebagai backend cache terdistribusi:
builder.Services.AddCosmosCache((CosmosCacheOptions options) =>
{
options.ContainerName = builder.Configuration["CosmosCache:ContainerName"];
options.DatabaseName = builder.Configuration["CosmosCache:DatabaseName"];
options.ClientBuilder = new CosmosClientBuilder(
builder.Configuration["CosmosCache:ConnectionString"]);
options.CreateIfNotExists = true;
});
Cache PostgreSQL
Memerlukan paket NuGet Microsoft.Extensions.Caching.Postgres.
appsettings.json:
{
"ConnectionStrings": {
"PostgresCache": "Host=localhost;Database=mydb;Username=myuser;Password=mypassword"
},
"PostgresCache": {
"SchemaName": "public",
"TableName": "token_cache",
"CreateIfNotExists": true
}
}
Kemudian daftarkan cache PostgreSQL di Program.cs:
builder.Services.AddDistributedPostgresCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache");
options.SchemaName = builder.Configuration["PostgresCache:SchemaName"];
options.TableName = builder.Configuration["PostgresCache:TableName"];
options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists");
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
→ Pelajari selengkapnya tentang konfigurasi cache terdistribusi
Singgahan sesi (tidak disarankan)
Perhatian
Penembolokan berbasis sesi memiliki batasan yang signifikan. Gunakan cache terdistribusi sebagai gantinya.
Contoh berikut menunjukkan cache token berbasis sesi sebagai referensi.
using Microsoft.Identity.Web.TokenCacheProviders.Session;
// In Program.cs
builder.Services.AddSession();
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddSessionTokenCaches();
// In middleware pipeline
app.UseSession(); // Must be before UseAuthentication()
app.UseAuthentication();
app.UseAuthorization();
Limitations:
- Masalah ukuran cookie - Token ID besar dengan banyak klaim menyebabkan masalah
-
Konflik Lingkup - Tidak dapat digunakan bersama dengan singleton
TokenAcquisition(misalnya, Microsoft Graph SDK) - Afinitas sesi diperlukan - Tidak berfungsi dengan baik dalam skenario penyeimbangan beban
- Tidak disarankan - Gunakan cache terdistribusi sebagai gantinya
Konfigurasi tingkat lanjut
Opsi ini memungkinkan Anda menyempurnakan perilaku cache untuk kebijakan performa, keamanan, dan pengeluaran.
Kontrol L1 cache
Cache L1 (dalam memori) meningkatkan performa saat Anda menggunakan cache terdistribusi. Kode berikut mengonfigurasi ukuran dan perilaku cache L1:
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
// Control L1 cache size (default: 500 MB)
options.L1CacheOptions.SizeLimit = 100 * 1024 * 1024; // 100 MB
// Disable L1 cache if session affinity is not available
// (forces all requests to use L2 cache for consistency)
options.DisableL1Cache = false;
});
Kapan harus menonaktifkan L1:
- Tidak ada afinitas sesi dalam penyeimbang beban (load balancer)
- Pengguna sering kali diminta untuk Autentikasi Multi-Faktor karena inkonsistensi cache
- Trade-off: Kecepatan akses L2 lebih rendah (~30ms vs ~10ms)
Kebijakan pengeluaran cache
Kebijakan pengeluaran mengontrol kapan token yang di-cache dihapus. Kode berikut ini menetapkan kedaluwarsa absolut dan kedaluwarsa geser:
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
// Absolute expiration (removed after this time, regardless of use)
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(72);
// Sliding expiration (renewed on each access)
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Anda juga dapat mengonfigurasi pengeluaran melalui appsettings.json:
{
"TokenCacheOptions": {
"AbsoluteExpirationRelativeToNow": "72:00:00",
"SlidingExpiration": "02:00:00"
}
}
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(
builder.Configuration.GetSection("TokenCacheOptions"));
Recommendations:
- Atur kedaluwarsa lebih lama dari masa pakai token (token biasanya kedaluwarsa dalam 1 jam)
- Default: Kedaluwarsa tergeser 90 menit
- Keseimbangan antara penggunaan memori dan pengalaman pengguna
- Pertimbangkan: 72 jam tetap + 2 jam fleksibel demi UX yang optimal
→ Pelajari selengkapnya tentang strategi pengeluaran cache
Enkripsi saat tidak aktif
Untuk melindungi data token sensitif dalam cache terdistribusi, aktifkan enkripsi melalui ASP.NET Core Perlindungan Data.
Mesin tunggal
Pada satu komputer, aktifkan enkripsi dengan penyedia Perlindungan Data bawaan:
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.Encrypt = true; // Uses ASP.NET Core Data Protection
});
Sistem terdistribusi (beberapa server)
Penting
Sistem terdistribusi tidak berbagi kunci enkripsi secara default. Anda harus mengonfigurasi berbagi kunci:
Azure Key Vault (disarankan):
Kode berikut mempertahankan kunci untuk Azure Blob Storage dan melindunginya dengan Azure Key Vault:
using Microsoft.AspNetCore.DataProtection;
builder.Services.AddDataProtection()
.PersistKeysToAzureBlobStorage(new Uri(builder.Configuration["DataProtection:BlobUri"]))
.ProtectKeysWithAzureKeyVault(
new Uri(builder.Configuration["DataProtection:KeyIdentifier"]),
new DefaultAzureCredential());
Berbasis sertifikat:
Kode berikut mempertahankan kunci ke berbagi file dan melindunginya dengan sertifikat X.509:
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
.ProtectKeysWithCertificate(
new X509Certificate2("current.pfx", builder.Configuration["CertPassword"]))
.UnprotectKeysWithAnyCertificate(
new X509Certificate2("current.pfx", builder.Configuration["CertPassword"]),
new X509Certificate2("previous.pfx", builder.Configuration["PrevCertPassword"]));
→ Pelajari selengkapnya tentang enkripsi dan perlindungan data
Pertimbangan performa cache
Gunakan perkiraan berikut untuk merencanakan kapasitas cache untuk aplikasi Anda.
Perkiraan ukuran token
| Jenis Token | Ukuran Umum | Per | Catatan |
|---|---|---|---|
| Token aplikasi | ~2 KB | Sumber Daya × Penyewa | Dikeluarkan secara otomatis |
| Token pengguna | ~7 KB | Sumber Daya × Penyewa × Pengguna | Pengosongan manual diperlukan |
| Token penyegaran | Variabel | Pengguna | Berumur panjang |
Perencanaan memori
Untuk 500 pengguna bersamaan yang memanggil 3 API:
- Token pengguna: 500 × 3 × 7 KB = 10,5 MB
- Dengan overhead: ~15-20 MB
Untuk 10.000 pengguna bersamaan:
- Token pengguna: 10.000 × 3 × 7 KB = 210 MB
- Dengan overhead: ~300-350 MB
Rekomendasi: Atur batas ukuran cache L1 berdasarkan pengguna bersamaan yang diharapkan.
Praktik terbaik
Ikuti panduan ini untuk memastikan penyimpanan sementara token yang andal dan efisien.
Menggunakan cache terdistribusi dalam produksi - Penting untuk penyebaran multi-server
Mengatur batas ukuran cache yang sesuai - Mencegah pertumbuhan memori yang tidak terbatas
Mengonfigurasi kebijakan pengusiran - Menyeimbangkan UX dan penggunaan memori
Mengaktifkan enkripsi untuk data sensitif - Melindungi token saat tidak aktif
Memantau kesehatan cache - Melacak tingkat hit, kegagalan, dan performa
Menangani kegagalan cache L2 dengan anggun - Cache L1 memastikan ketahanan
Menguji perilaku cache - Memverifikasi skenario hidupkan ulang dan failover
Jangan gunakan cache memori terdistribusi dalam produksi - Tidak persisten atau terdistribusi
Jangan gunakan cache sesi - Memiliki batasan yang signifikan
Jangan atur kedaluwarsa lebih pendek dari masa pakai token - Memaksa autentikasi ulang yang tidak perlu
Jangan lupa berbagi kunci enkripsi - Sistem terdistribusi memerlukan kunci bersama