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.
Sebarkan API web ASP.NET Core yang dilindungi dengan Microsoft. Identity.Web di belakang gateway API Azure dan proksi terbalik, termasuk Azure API Management (APIM), Azure Front Door, dan Azure Application Gateway.
Memahami persyaratan gateway
Saat Anda menyebarkan API yang dilindungi di belakang gateway, Anda harus menangani beberapa masalah:
- Header yang diteruskan - Mempertahankan konteks permintaan asli (skema, host, IP)
- Validasi token - Pastikan klaim audiens cocok dengan URL gateway
- Konfigurasi CORS - Menangani permintaan lintas asal dengan benar
- Endpoint kesehatan - Memberikan pemeriksaan kesehatan yang tidak diautentikasi
- Routing berbasis jalur - Mendukung awalan jalur pada tingkat gateway
- Penghentian SSL/TLS - Tangani HTTPS dengan benar saat gateway mengakhiri SSL
Meninjau skenario gateway umum
Pilih gateway berdasarkan kebutuhan Anda. Bagian berikut ini menjelaskan layanan gateway Azure yang paling umum untuk API yang dilindungi.
Azure API Management (APIM)
Kasus penggunaan: Gateway API Perusahaan dengan kebijakan, pembatasan tarif, transformasi
Arsitektur:
Client → Microsoft Entra ID → Token
Client → APIM (apim.azure-api.net) → Backend API (app.azurewebsites.net)
Pertimbangan utama:
- Kebijakan APIM dapat memvalidasi token JWT sebelum meneruskan ke backend
- API backend masih memvalidasi token
- Klaim audiens harus cocok dengan URL APIM atau URL backend (dikustomisasi sesuai kebutuhan)
Azure Front Door
Kasus penggunaan: Penyeimbangan beban global, CDN, perlindungan DDoS
Arsitektur:
Client → Microsoft Entra ID → Token
Client → Front Door (azurefd.net) → Backend API (regional endpoints)
Pertimbangan utama:
- Front Door meneruskan permintaan dengan
X-Forwarded-*header - Penghentian SSL/TLS di Front Door
- Konfigurasi untuk validasi audiens token diperlukan
Azure Application Gateway
Kasus penggunaan: Penyeimbangan beban regional, WAF, perutean berdasarkan jalur
Arsitektur:
Client → Microsoft Entra ID → Token
Client → Application Gateway → Backend API (multiple instances)
Pertimbangan utama:
- Integrasi dengan Web Application Firewall (WAF)
- Aturan perutean berbasis jalur
- Pemeriksaan kesehatan backend menggunakan endpoint yang tidak diautentikasi.
Mengonfigurasi pola-pola umum
Terapkan pola konfigurasi ini untuk memastikan API yang dilindungi berfungsi dengan benar di belakang gateway apa pun.
1. Middleware header yang diteruskan
Selalu konfigurasikan middleware "forwarded headers" ketika berada di belakang gateway. Kode berikut mendaftarkan middleware dan mengaturnya untuk dijalankan sebelum autentikasi:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
// Configure forwarded headers BEFORE authentication
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost;
// Clear known networks/proxies to accept forwarded headers from any source
// (Azure infrastructure will be the proxy)
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
// Limit to specific headers if needed
options.ForwardedForHeaderName = "X-Forwarded-For";
options.ForwardedProtoHeaderName = "X-Forwarded-Proto";
options.ForwardedHostHeaderName = "X-Forwarded-Host";
});
// Add authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
var app = builder.Build();
// USE forwarded headers BEFORE authentication middleware
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.Run();
Middleware header yang diteruskan sangat penting karena:
- Mempertahankan alamat IP klien asli untuk pengelogan
-
HttpContext.Request.SchemeMemastikan mencerminkan skema HTTPS asli - Menyediakan header yang benar
Hostuntuk URL pengalihan dan validasi token
2. Konfigurasi audiens token
Opsi A: Terima kedua URL gateway dan backend
Tambahkan beberapa audiens yang valid dalam konfigurasi Anda appsettings.json :
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"Audience": "api://your-client-id",
"TokenValidationParameters": {
"ValidAudiences": [
"api://your-client-id",
"https://your-backend.azurewebsites.net",
"https://your-apim.azure-api.net"
]
}
}
}
Atau, konfigurasikan beberapa audiens secara terprogram di Program.cs:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
// Customize token validation to accept multiple audiences
builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
var existingValidation = options.TokenValidationParameters.AudienceValidator;
options.TokenValidationParameters.AudienceValidator = (audiences, token, parameters) =>
{
var validAudiences = new[]
{
"api://your-client-id",
"https://your-backend.azurewebsites.net",
"https://your-apim.azure-api.net",
builder.Configuration["AzureAd:ClientId"] // Also accept ClientId
};
return audiences.Any(a => validAudiences.Contains(a, StringComparer.OrdinalIgnoreCase));
};
});
Opsi B: Menulis ulang audiens dalam kebijakan APIM
Konfigurasikan APIM untuk memvalidasi klaim audiens sebelum meneruskan ke backend:
<policies>
<inbound>
<validate-jwt header-name="Authorization" failed-validation-httpcode="401">
<openid-config url="https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>api://your-client-id</audience>
</audiences>
</validate-jwt>
<!-- Optionally modify token claims for backend -->
<set-header name="X-Gateway-Validated" exists-action="override">
<value>true</value>
</set-header>
</inbound>
</policies>
3. Konfigurasi titik akhir kesehatan
Gateway memerlukan titik akhir kesehatan yang tidak diautentikasi untuk pemeriksaan. Petakan titik akhir kesehatan sebelum middleware autentikasi untuk melewati validasi token:
var app = builder.Build();
// Health endpoint BEFORE authentication middleware
app.MapGet("/health", () => Results.Ok(new { status = "healthy" }))
.AllowAnonymous();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
// Protected endpoints require authentication
app.MapControllers();
app.Run();
Atau, gunakan kerangka kerja Pemeriksaan Kesehatan ASP.NET Core bawaan untuk pelaporan kesehatan yang lebih kaya:
using Microsoft.Extensions.Diagnostics.HealthChecks;
builder.Services.AddHealthChecks()
.AddCheck("api", () => HealthCheckResult.Healthy());
var app = builder.Build();
app.MapHealthChecks("/health").AllowAnonymous();
app.MapHealthChecks("/ready").AllowAnonymous();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
4. Konfigurasi CORS di belakang gateway
Saat Anda menggunakan Azure Front Door atau APIM dengan aplikasi frontend, konfigurasikan CORS untuk mengizinkan permintaan dari asal gateway Anda:
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowGateway", policy =>
{
policy.WithOrigins(
"https://your-apim.azure-api.net",
"https://your-frontend.azurefd.net",
"https://your-app.azurewebsites.net"
)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials(); // If using cookies
});
});
var app = builder.Build();
app.UseForwardedHeaders();
app.UseCors("AllowGateway");
app.UseAuthentication();
app.UseAuthorization();
app.Run();
Penting
CORS harus dikonfigurasi setelah header yang diteruskan dan sebelum autentikasi.
Integrasikan dengan Azure API Management
Bagian ini menyediakan konfigurasi lengkap untuk menyebarkan API yang dilindungi di belakang Azure API Management.
Mengonfigurasi API backend
Siapkan header yang diteruskan dan autentikasi Microsoft Entra ID di Program.cs:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Forwarded headers for APIM
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.All;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
// Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
var app = builder.Build();
// Middleware order matters
app.UseForwardedHeaders();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Tambahkan konfigurasi Microsoft Entra ke appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-backend-api-client-id",
"Audience": "api://your-backend-api-client-id"
}
}
Menambahkan kebijakan masuk APIM untuk validasi JWT
Tentukan kebijakan masuk yang memvalidasi token JWT, menerapkan pembatasan tarif, dan meneruskan permintaan ke backend:
<policies>
<inbound>
<base />
<!-- Validate JWT token -->
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized">
<openid-config url="https://login.microsoftonline.com/{your-tenant-id}/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>api://your-backend-api-client-id</audience>
</audiences>
<issuers>
<issuer>https://login.microsoftonline.com/{your-tenant-id}/v2.0</issuer>
</issuers>
<required-claims>
<claim name="scp" match="any">
<value>access_as_user</value>
</claim>
</required-claims>
</validate-jwt>
<!-- Rate limiting -->
<rate-limit calls="100" renewal-period="60" />
<!-- Forward original host header -->
<set-header name="X-Forwarded-Host" exists-action="override">
<value>@(context.Request.OriginalUrl.Host)</value>
</set-header>
<!-- Forward to backend -->
<set-backend-service base-url="https://your-backend.azurewebsites.net" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Mengonfigurasi pengaturan APIM API
Gunakan nilai bernama dan pengaturan API berikut untuk menyelesaikan konfigurasi APIM:
Nilai Bernama (untuk kemudahan penggunaan ulang):
-
tenant-id: ID penyewa Microsoft Entra Anda -
backend-api-client-id: ID klien Backend API -
backend-base-url:https://your-backend.azurewebsites.net
Pengaturan API:
-
Akhiran URL API:
/api(awalan jalur opsional) - URL layanan web: Diatur melalui kebijakan dengan nilai yang telah diberi nama
- Langganan diperlukan: Ya (menambahkan lapisan keamanan lain)
Mengonfigurasi aplikasi klien
Aplikasi klien meminta token untuk API backend, bukan APIM. Kode berikut memperoleh token dan memanggil API melalui titik akhir APIM:
// Client app requests token
var result = await app.AcquireTokenSilent(
scopes: new[] { "api://your-backend-api-client-id/access_as_user" },
account)
.ExecuteAsync();
// Call APIM URL with token
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", result.AccessToken);
// Add APIM subscription key
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "your-subscription-key");
var response = await client.GetAsync("https://your-apim.azure-api.net/api/weatherforecast");
Integrasikan dengan Azure Front Door
Konfigurasikan API yang dilindungi untuk distribusi global di belakang Azure Front Door.
Mengonfigurasi API back-end
Siapkan header yang diteruskan untuk Azure Front Door di Program.cs:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
// Configure for Azure Front Door
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost;
// Accept headers from any source (Azure Front Door)
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
// Front Door specific headers
options.ForwardedForHeaderName = "X-Forwarded-For";
options.ForwardedProtoHeaderName = "X-Forwarded-Proto";
});
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
var app = builder.Build();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Mengonfigurasi sumber Front Door
Selesaikan langkah-langkah berikut di portal Azure untuk menyiapkan asal Front Door:
- Membuat profil Front Door
- Tambahkan grup asal dengan instance API backend Anda
- Mengonfigurasi pemeriksaan kesehatan pada
/healthtitik akhir - Mengatur penerusan hanya HTTPS
- Mengaktifkan kebijakan WAF (opsional)
Pengaturan Health Probe:
-
Jalur:
/health - Protokol: HTTPS
- Metode: GET
- Interval: 30 detik
Menangani beberapa wilayah
Saat Anda menyebarkan ke beberapa wilayah di belakang Front Door, tambahkan kesadaran wilayah untuk pengelogan dan diagnostik:
// Add region awareness for logging/diagnostics
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
app.Use(async (context, next) =>
{
// Log the actual client IP and region
var clientIp = context.Connection.RemoteIpAddress?.ToString();
var forwardedFor = context.Request.Headers["X-Forwarded-For"].ToString();
var frontDoorId = context.Request.Headers["X-Azure-FDID"].ToString();
// Add to logger scope or response headers
context.Response.Headers.Add("X-Served-By-Region",
builder.Configuration["Region"] ?? "unknown");
await next();
});
Memvalidasi token dengan Front Door
Jika klien meminta token yang dibatasi pada URL Front Door, tambahkan ke daftar audiens yang valid.
builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters.ValidAudiences = new[]
{
"api://your-backend-api-client-id",
"https://your-frontend.azurefd.net", // Front Door URL
builder.Configuration["AzureAd:ClientId"]
};
});
Mengintegrasikan dengan Azure Application Gateway
Konfigurasikan API yang dilindungi di belakang Azure Application Gateway dengan dukungan Web Application Firewall (WAF).
Mengonfigurasi API backend
Siapkan header yang diteruskan untuk Application Gateway di Program.cs:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
// Application Gateway uses standard forwarded headers
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddHealthChecks();
var app = builder.Build();
// Health endpoint for Application Gateway probes
app.MapHealthChecks("/health").AllowAnonymous();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Mengonfigurasi pengaturan Application Gateway
Atur pengaturan berikut untuk backend, pemeriksaan kesehatan, dan WAF di portal Azure:
Pengaturan Backend:
- Protokol: HTTPS (disarankan) atau HTTP
- Port: 443 atau 80
- Mengesampingkan jalur backend: Tidak (kecuali diperlukan)
-
Peninjau kustom: Ya, menunjuk ke
/health
Sonde Kesehatan:
- Protokol: HTTPS atau HTTP
- Host: Biarkan default atau tentukan
-
Jalur:
/health - Interval: 30 detik
- Ambang tidak sehat: 3
Kebijakan WAF:
- Mengaktifkan WAF dengan ruleset OWASP 3.2
-
Penting: Pastikan token JWT di
Authorizationheader tidak diblokir - Anda mungkin perlu membuat pengecualian WAF untuk
RequestHeaderNamesberisi "Otorisasi"
Menyiapkan perutean berbasis jalur
Saat Anda menggunakan aturan perutean berbasis jalur, konfigurasikan API backend Anda untuk menangani awalan jalur:
// Backend API should work regardless of path prefix
var app = builder.Build();
// Option 1: Use path base (if gateway adds prefix)
app.UsePathBase("/api/v1");
// Option 2: Configure routing explicitly
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Aturan Gerbang Aplikasi:
-
Jalur:
/api/v1/* - Target backend: Kumpulan backend Anda
- Pengaturan backend: Gunakan pengaturan yang dikonfigurasi
Pemecahan Masalah Umum
Gunakan solusi ini untuk mengatasi masalah paling umum saat menyebarkan API yang dilindungi di belakang gateway.
Masalah: 401 Tidak Sah setelah implementasi di balik gateway
Gejala:
- API berfungsi secara lokal tetapi mengembalikan 401 di belakang gateway
- Token tampaknya valid ketika didekodekan pada jwt.ms
Kemungkinan penyebabnya:
Ketidakcocokan klaim audiens
# Check token audience # Decode token and verify 'aud' claim matches one of: # - api://your-client-id # - https://your-backend.azurewebsites.net # - https://your-gateway-urlMiddleware header yang diteruskan hilang
// Ensure this is BEFORE authentication app.UseForwardedHeaders(); app.UseAuthentication();Masalah pengalihan HTTPS
// If gateway terminates SSL, may need to disable or configure carefully if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); }
Solution:
- Mengaktifkan pengelogan debug untuk melihat detail validasi token
- Menambahkan beberapa audiens yang valid dalam validasi token
- Verifikasi bahwa
X-Forwarded-*header diteruskan oleh gateway
Masalah: Pemeriksaan kesehatan gagal
Gejala:
- Gateway menandai backend sebagai tidak sehat
- Titik akhir kesehatan mengembalikan 401
Solution:
Pastikan endpoint kesehatan dijalankan sebelum middleware autentikasi:
// Ensure health endpoint is BEFORE authentication
app.MapHealthChecks("/health").AllowAnonymous();
// Alternative: Use custom middleware
app.Map("/health", healthApp =>
{
healthApp.Run(async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("healthy");
});
});
app.UseAuthentication(); // Health endpoint bypasses this
Masalah: Kesalahan CORS di belakang Front Door
Gejala:
- Permintaan OPSI Preflight gagal
- Konsol browser menunjukkan kesalahan CORS
Solution:
Tambahkan Front Door dan asal frontend Anda ke kebijakan CORS:
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins(
"https://your-frontend.azurefd.net",
"https://your-app.com"
)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
var app = builder.Build();
app.UseForwardedHeaders();
app.UseCors(); // Before authentication
app.UseAuthentication();
app.UseAuthorization();
Masalah: Peringatan "Header yang diteruskan" dalam log
Gejala:
Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware: Unknown proxy
Solution:
Hapus jaringan dan proksi yang diketahui untuk menerima header yang diteruskan dari infrastruktur Azure:
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
// Clear known networks to accept from any proxy
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
// Or explicitly add Azure IP ranges (more secure but complex)
// options.KnownProxies.Add(IPAddress.Parse("20.x.x.x"));
});
Masalah: APIM mengembalikan 401 tetapi backend mengembalikan 200
Gejala:
- Token sah untuk backend
- Kebijakan APIM
validate-jwtgagal
Solution:
Pastikan audiens kebijakan APIM sesuai dengan audiens token.
<validate-jwt header-name="Authorization">
<openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
<audiences>
<!-- Must match the 'aud' claim in your token -->
<audience>api://your-backend-api-client-id</audience>
</audiences>
</validate-jwt>
Masalah: Konflik beberapa skema autentikasi
Gejala:
- Menggunakan token JWT dan skema lainnya
- Skema yang salah dipilih
Solution:
Tentukan skema autentikasi secara eksplisit di pengontrol:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.AddScheme<MyCustomOptions, MyCustomHandler>("CustomScheme", options => {});
// In controller, specify scheme explicitly
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class WeatherForecastController : ControllerBase
{
// ...
}
Ikuti praktik terbaik
Terapkan praktik ini untuk membangun penyebaran API yang aman dan tangguh di belakang gateway.
1. Pertahanan secara mendalam
Selalu validasi token di API backend, meskipun gateway memvalidasinya:
// Gateway validates token (APIM policy)
// Backend ALSO validates token (Microsoft.Identity.Web)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
Konfigurasi gateway dapat berubah dan token dapat diputar ulang. Pertahanan secara mendalam sangat penting untuk keamanan.
2. Gunakan identitas terkelola untuk komunikasi gateway-ke-backend
Jika gateway Anda memanggil backend dengan identitasnya sendiri, konfigurasikan backend untuk menerima token pengguna dan token identitas terkelola:
// Backend accepts both user tokens and gateway's managed identity
builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters.ValidAudiences = new[]
{
"api://backend-api-client-id", // User tokens
"https://management.azure.com" // Managed identity tokens (if applicable)
};
});
3. Memantau metrik gerbang
Lacak metrik utama ini untuk mempertahankan visibilitas dalam implementasi gateway Anda:
- Tingkat kesalahan 401/403
- Kegagalan validasi token
- Kegagalan sensor kesehatan
- Header yang diteruskan (untuk debugging)
4. Gunakan Application Insights
Tambahkan telemetri Application Insights untuk mencatat properti permintaan khusus milik gateway.
builder.Services.AddApplicationInsightsTelemetry();
// Log custom properties
app.Use(async (context, next) =>
{
var telemetry = context.RequestServices.GetRequiredService<TelemetryClient>();
telemetry.TrackEvent("ApiRequest", new Dictionary<string, string>
{
["ForwardedFor"] = context.Request.Headers["X-Forwarded-For"],
["OriginalHost"] = context.Request.Headers["X-Forwarded-Host"],
["Gateway"] = "APIM" // or "FrontDoor", "AppGateway"
});
await next();
});
Pisahkan status kesehatan dari status siap
Gunakan titik akhir yang berbeda untuk keaktifan (apakah layanan berjalan?) dan kesiapan (dapatkah layanan menerima lalu lintas?) pemeriksaan:
// Health: Is the service running?
app.MapGet("/health", () => Results.Ok()).AllowAnonymous();
// Ready: Can the service accept traffic?
app.MapHealthChecks("/ready", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("ready")
}).AllowAnonymous();
builder.Services.AddHealthChecks()
.AddCheck("database", () => /* check DB */ , tags: new[] { "ready" })
.AddCheck("cache", () => /* check cache */ , tags: new[] { "ready" });
6. Dokumentasikan konfigurasi gateway Anda
Buat halaman README atau wiki yang mencakup:
- Gateway mana yang sedang digunakan
- Harapan audiens terhadap token
- Konfigurasi CORS
- Titik akhir pemeriksaan kesehatan
- Konfigurasi header yang diteruskan
- Prosedur putar kembali darurat
Buat contoh lengkap dengan Azure API Management
Bagian ini menyediakan contoh lengkap dan siap produksi dari API ASP.NET Core di belakang Azure API Management dengan autentikasi Microsoft Entra ID.
API Backend (ASP.NET Core)
Program.cs berikut mengatur pengalihan header, autentikasi Microsoft Entra, pengecekan kesehatan sistem, dan Application Insights:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Forwarded headers for APIM
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.All;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
// Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph()
.AddInMemoryTokenCaches();
// Application Insights
builder.Services.AddApplicationInsightsTelemetry();
// Health checks
builder.Services.AddHealthChecks();
builder.Services.AddControllers();
var app = builder.Build();
// Health endpoint (unauthenticated)
app.MapHealthChecks("/health").AllowAnonymous();
// Middleware order is critical
app.UseForwardedHeaders();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Tambahkan konfigurasi Microsoft Entra dan Application Insights berikut ke appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "backend-api-client-id",
"Audience": "api://backend-api-client-id"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Identity.Web": "Debug"
}
},
"ApplicationInsights": {
"ConnectionString": "your-connection-string"
}
}
Pengontrol berikut memerlukan header autentikasi dan log yang diteruskan untuk penelusuran kesalahan:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web.Resource;
[Authorize]
[ApiController]
[Route("[controller]")]
[RequiredScope("access_as_user")]
public class WeatherForecastController : ControllerBase
{
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IActionResult Get()
{
// Log forwarded headers for debugging
var forwardedFor = HttpContext.Request.Headers["X-Forwarded-For"];
var forwardedHost = HttpContext.Request.Headers["X-Forwarded-Host"];
_logger.LogInformation(
"Request from {ForwardedFor} via {ForwardedHost}",
forwardedFor,
forwardedHost);
return Ok(new[] { "Weather", "Forecast", "Data" });
}
}
Konfigurasi APIM
Kebijakan masuk berikut memvalidasi token JWT, menerapkan pembatasan tarif, meneruskan header, dan mengonfigurasi CORS:
<policies>
<inbound>
<base />
<!-- Rate limiting per subscription -->
<rate-limit-by-key calls="100" renewal-period="60"
counter-key="@(context.Subscription.Id)" />
<!-- Validate JWT -->
<validate-jwt header-name="Authorization"
failed-validation-httpcode="401"
failed-validation-error-message="Unauthorized">
<openid-config url="https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>api://backend-api-client-id</audience>
</audiences>
<issuers>
<issuer>https://login.microsoftonline.com/{tenant-id}/v2.0</issuer>
</issuers>
<required-claims>
<claim name="scp" match="any">
<value>access_as_user</value>
</claim>
</required-claims>
</validate-jwt>
<!-- Forward headers -->
<set-header name="X-Forwarded-Host" exists-action="override">
<value>@(context.Request.OriginalUrl.Host)</value>
</set-header>
<set-header name="X-Forwarded-Proto" exists-action="override">
<value>@(context.Request.OriginalUrl.Scheme)</value>
</set-header>
<!-- Backend URL -->
<set-backend-service base-url="https://your-backend.azurewebsites.net" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<!-- Add CORS headers if needed -->
<cors>
<allowed-origins>
<origin>https://your-frontend.com</origin>
</allowed-origins>
<allowed-methods>
<method>GET</method>
<method>POST</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
</cors>
</outbound>
<on-error>
<base />
</on-error>
</policies>