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.
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 10 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 10 dari artikel ini.
Oleh Chris Ross
Dalam konfigurasi yang direkomendasikan untuk ASP.NET Core, aplikasi dihosting menggunakan ASP.NET Core Module (ANCM) untuk IIS, Nginx, atau Apache. Proxy server, load balancer, dan perangkat jaringan lainnya sering mengaburkan informasi tentang permintaan sebelum mencapai aplikasi.
- Ketika permintaan HTTPS diproksi melalui HTTP, skema asli (HTTPS) hilang dan harus diteruskan di header.
- Karena aplikasi menerima permintaan dari proksi dan bukan sumber sebenarnya di Internet atau jaringan perusahaan, alamat IP klien asal juga harus diteruskan di header.
Informasi ini mungkin penting dalam pemrosesan permintaan, misalnya dalam pengalihan, autentikasi, pembuatan tautan, evaluasi kebijakan, dan geolokasi klien.
Aplikasi yang dimaksudkan untuk dijalankan di farm web sebaiknya merujuk ke Host ASP.NET Core di farm web.
Header yang diteruskan
Menurut konvensi, proksi meneruskan informasi di header HTTP.
| Kepala Halaman | Deskripsi |
|---|---|
X-Forwarded-For (XFF) |
Menyimpan informasi tentang klien yang memulai permintaan dan proksi berikutnya dalam rantai proksi. Parameter ini mungkin berisi alamat IP dan, secara opsional, nomor port. Dalam rantai server proksi, parameter pertama menunjukkan klien tempat permintaan pertama kali dibuat. Pengidentifikasi proksi berikutnya mengikuti. Proksi terakhir dalam rantai tidak ada dalam daftar parameter. Alamat IP proksi terakhir, dan secara opsional nomor port, tersedia sebagai alamat IP jarak jauh di lapisan transportasi. |
X-Forwarded-Proto (XFP) |
Nilai skema asal, HTTP atau HTTPS. Nilai mungkin juga merupakan daftar skema jika permintaan telah melintasi beberapa proksi. |
X-Forwarded-Host (XFH) |
Nilai asli bidang header Host. Biasanya, proksi tidak mengubah header Host. Lihat Microsoft Security Advisory CVE-2018-0787 untuk informasi tentang kerentanan elevasi hak istimewa yang memengaruhi sistem di mana proksi tidak memvalidasi atau membatasi header Host ke nilai yang diketahui baik. |
X-Forwarded-Prefix |
Jalur dasar asli yang diminta oleh klien. Header ini dapat berguna bagi aplikasi untuk menghasilkan URL, pengalihan, atau tautan dengan benar kembali ke klien. |
Middleware Forwarded Headers, ForwardedHeadersMiddleware, membaca header ini dan mengisi bidang terkait pada HttpContext.
Pembaruan middleware:
-
HttpContext.Connection.RemoteIpAddress: Mengatur menggunakan nilai headerX-Forwarded-For. Pengaturan tambahan memengaruhi bagaimana middleware mengaturRemoteIpAddress. Untuk detailnya, lihat pengaturan Middleware Forwarded Headers. Nilai yang telah dikonsumsi dihapus dariX-Forwarded-For, dan nilai lama dariHttpContext.Connection.RemoteIpAddressdisimpan dalamX-Original-For. Catatan: Proses ini mungkin diulang beberapa kali jika ada beberapa nilai dalamX-Forwarded-For/Proto/Host/Prefix, yang mengakibatkan beberapa nilai dipindahkan keX-Original-*, termasuk yang asliRemoteIpAddress/Host/Scheme/PathBase. -
HttpContext.Request.Scheme: Mengatur menggunakan nilai headerX-Forwarded-Proto. Nilai yang digunakan dihapus dariX-Forwarded-Proto, dan nilai lamaHttpContext.Request.Schemedisimpan dalamX-Original-Proto. -
HttpContext.Request.Host: Mengatur menggunakan nilai headerX-Forwarded-Host. Nilai yang digunakan dihapus dariX-Forwarded-Host, dan nilai lamaHttpContext.Request.Hostdisimpan dalamX-Original-Host. -
HttpContext.Request.PathBase: Mengatur menggunakan nilai headerX-Forwarded-Prefix. Nilai yang digunakan dihapus dariX-Forwarded-Prefix, dan nilai lamaHttpContext.Request.PathBasedisimpan dalamX-Original-Prefix.
Untuk informasi selengkapnya tentang sebelumnya, lihat masalah GitHub ini.
Pengaturan default Middleware Header yang Diteruskan dapat dikonfigurasi. Untuk pengaturan default:
- Hanya ada satu proksi antara aplikasi dan sumber permintaan.
- Hanya alamat loopback yang dikonfigurasi untuk proksi yang diketahui dan jaringan yang diketahui.
- Header yang diteruskan diberi nama
X-Forwarded-For, ,X-Forwarded-ProtoX-Forwarded-HostdanX-Forwarded-Prefix. - Nilai
ForwardedHeadersadalahForwardedHeaders.None. Pengirim yang diinginkan harus diatur di sini untuk mengaktifkan middleware.
Tidak semua perangkat jaringan secara otomatis menambahkan header X-Forwarded-For dan X-Forwarded-Proto tanpa konfigurasi tambahan. Lihat panduan produsen perangkat Anda jika permintaan terproksi tidak berisi header ini ketika mencapai aplikasi. Jika perangkat menggunakan nama header yang berbeda dari X-Forwarded-For dan X-Forwarded-Proto, atur opsi ForwardedForHeaderName dan ForwardedProtoHeaderName agar sesuai dengan nama header yang digunakan oleh perangkat. Untuk informasi selengkapnya, lihat Opsi Middleware Header yang Diteruskan dan Konfigurasi untuk proksi yang menggunakan nama header yang berbeda.
Modul IIS/IIS Express dan ASP.NET Core
IIS Integration Middleware mengaktifkan Forwarded Headers Middleware secara default saat aplikasi dihosting out-of-process di belakang IIS dan ASP.NET Core Module (ANCM) untuk IIS. Middleware Header yang Diteruskan diaktifkan untuk dijalankan terlebih dahulu di alur middleware dengan konfigurasi terbatas khusus untuk Modul ASP.NET Core. Konfigurasi terbatas karena isu kepercayaan terhadap header yang diteruskan, misalnya, IP spoofing. Middleware dikonfigurasi untuk meneruskan header X-Forwarded-For dan X-Forwarded-Proto serta dibatasi hanya pada satu proxy localhost. Jika konfigurasi tambahan diperlukan, lihat opsi Middleware Header yang Diteruskan.
Skenario server proksi dan load balancer lainnya
Di luar penggunaan Integrasi IIS saat menghosting secara di luar proses, Middleware Header yang Diteruskan tidak diaktifkan secara default. Middleware "Forwarded Headers" harus diaktifkan agar aplikasi memproses header yang diteruskan dengan UseForwardedHeaders. Setelah mengaktifkan middleware, jika tidak ada ForwardedHeadersOptions yang ditentukan ke middleware, ForwardedHeadersOptions.ForwardedHeaders default adalah ForwardedHeaders.None.
Konfigurasikan middleware dengan ForwardedHeadersOptions untuk meneruskan X-Forwarded-For header dan X-Forwarded-Proto .
Urutan Middleware Header yang Diteruskan
Middleware Pengalihan Header harus dijalankan sebelum middleware lainnya. Urutan ini memastikan bahwa middleware yang mengandalkan informasi header yang diteruskan dapat memanfaatkan data header untuk pemrosesan. Middleware Penerusan Header dapat berjalan setelah proses diagnostik dan penanganan kesalahan, tetapi harus dijalankan terlebih dahulu sebelum memanggil UseHsts.
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseForwardedHeaders();
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Atau, panggil UseForwardedHeaders sebelum diagnostik:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
var app = builder.Build();
app.UseForwardedHeaders();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Catatan
Jika tidak ada ForwardedHeadersOptions yang ditentukan atau diterapkan langsung ke metode ekstensi dengan UseForwardedHeaders, header default yang akan diteruskan adalah ForwardedHeaders.None. Properti ForwardedHeaders harus dikonfigurasi dengan header untuk diteruskan.
Konfigurasi Nginx
Untuk meneruskan X-Forwarded-For header dan X-Forwarded-Proto , lihat Host ASP.NET Core di Linux dengan Nginx.
Konfigurasi Apache
X-Forwarded-For ditambahkan secara otomatis. Untuk informasi selengkapnya, lihat Modul Apache mod_proxy: Header Permintaan Proksi Terbalik.
Opsi Middleware Header yang Diteruskan
ForwardedHeadersOptions mengontrol perilaku Forwarded Headers Middleware. Contoh berikut mengubah nilai default:
- Membatasi jumlah entri dalam header yang diteruskan ke
2. - Menambahkan alamat proksi yang diketahui dari
127.0.10.1. - Mengubah nama header yang diteruskan dari default
X-Forwarded-ForkeX-Forwarded-For-My-Custom-Header-Name.
using System.Net;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardLimit = 2;
options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});
var app = builder.Build();
app.UseForwardedHeaders();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
| Opsi | Deskripsi |
|---|---|
| AllowedHosts | Membatasi host berdasarkan header X-Forwarded-Host ke nilai yang disediakan.
IList<string>. |
| ForwardedForHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XForwardedForHeaderName. Opsi ini digunakan ketika proksi/penerus tidak menggunakan X-Forwarded-For header tetapi menggunakan beberapa header lain untuk meneruskan informasi.Default adalah X-Forwarded-For. |
| ForwardedHeaders | Mengidentifikasi penerus mana yang harus diproses. Lihat ForwardedHeaders Enum untuk daftar bidang yang berlaku. Nilai umum yang ditetapkan ke properti ini adalah ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.Nilai defaultnya adalah ForwardedHeaders.None. |
| ForwardedHostHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XForwardedHostHeaderName. Opsi ini digunakan ketika proksi/penerus tidak menggunakan X-Forwarded-Host header tetapi menggunakan beberapa header lain untuk meneruskan informasi.Default adalah X-Forwarded-Host. |
| ForwardedProtoHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XForwardedProtoHeaderName. Opsi ini digunakan ketika proksi/penerus tidak menggunakan X-Forwarded-Proto header tetapi menggunakan beberapa header lain untuk meneruskan informasi.Default adalah X-Forwarded-Proto. |
| ForwardLimit | Membatasi jumlah entri dalam header yang diproses. Atur ke null untuk menonaktifkan batas, tetapi ini hanya boleh dilakukan jika KnownProxies atau KnownNetworks dikonfigurasi. Mengatur nilai selainnull adalah tindakan pencegahan (tetapi bukan jaminan) untuk melindungi dari proksi yang salah dikonfigurasi dan permintaan berbahaya yang tiba dari saluran samping di jaringan.Middleware Header yang diteruskan memproses header dalam urutan terbalik dari kanan ke kiri. Jika nilai default ( 1) digunakan, hanya nilai paling kanan dari header yang diproses kecuali nilai ForwardLimit ditingkatkan.Default adalah 1. |
| KnownNetworks | Rentang alamat jaringan yang diketahui untuk menerima header yang diteruskan. Berikan rentang IP menggunakan notasi Classless Interdomain Routing (CIDR). Jika server menggunakan soket mode ganda, alamat IPv4 disediakan dalam format IPv6 (misalnya, 10.0.0.1 dalam IPv4 yang diwakili dalam IPv6 sebagai ::ffff:10.0.0.1). Lihat IPAddress.MapToIPv6. Tentukan apakah format ini diperlukan dengan melihat HttpContext.Connection.RemoteIpAddress.Defaultnya adalah IList<IPNetwork> yang berisi satu entri untuk new IPNetwork(IPAddress.Loopback, 8). |
| KnownProxies | Alamat proksi yang diketahui untuk menerima header yang diteruskan. Gunakan KnownProxies untuk menentukan kecocokan alamat IP yang tepat.Jika server menggunakan soket mode ganda, alamat IPv4 disediakan dalam format IPv6 (misalnya, 10.0.0.1 dalam IPv4 yang diwakili dalam IPv6 sebagai ::ffff:10.0.0.1). Lihat IPAddress.MapToIPv6. Tentukan apakah format ini diperlukan dengan melihat HttpContext.Connection.RemoteIpAddress.Defaultnya adalah IList<IPAddress> yang berisi satu entri untuk IPAddress.IPv6Loopback. |
| OriginalForHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XOriginalForHeaderName. Default adalah X-Original-For. |
| OriginalHostHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XOriginalHostHeaderName. Default adalah X-Original-Host. |
| OriginalProtoHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XOriginalProtoHeaderName. Default adalah X-Original-Proto. |
| RequireHeaderSymmetry | Mengharuskan jumlah nilai header selaras dengan ForwardedHeadersOptions.ForwardedHeaders yang sedang diproses. Default dalam ASP.NET Core 1.x adalah true. Default dalam ASP.NET Core 2.0 atau yang lebih baru adalah false. |
Skenario dan kasus penggunaan
Ketika tidak dimungkinkan untuk menambahkan header yang diteruskan serta semua permintaan telah aman
Dalam beberapa kasus, mungkin tidak mungkin untuk menambahkan header yang diteruskan ke permintaan yang diproksikan ke aplikasi. Jika proksi memberlakukan bahwa semua permintaan eksternal publik adalah HTTPS, skema dapat diatur secara manual sebelum menggunakan semua jenis middleware:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
var app = builder.Build();
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next(context);
});
app.UseForwardedHeaders();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Kode ini dapat dinonaktifkan dengan variabel lingkungan atau pengaturan konfigurasi lainnya dalam lingkungan pengembangan atau penahapan:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
var app = builder.Build();
if (!app.Environment.IsProduction())
{
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next(context);
});
}
app.UseForwardedHeaders();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Bekerja dengan basis jalur dan proksi yang mengubah jalur permintaan
Beberapa proxy melewati path secara utuh tetapi dengan path dasar aplikasi yang harus dihapus supaya perutean berfungsi dengan baik. Middleware UsePathBaseExtensions.UsePathBase membagi jalur menjadi HttpRequest.Path dan jalur dasar aplikasi ke HttpRequest.PathBase.
Jika /foo adalah jalur dasar aplikasi untuk jalur proksi yang diteruskan sebagai /foo/api/1, middleware mengatur Request.PathBase ke /foo dan Request.Path ke /api/1 dengan perintah berikut:
app.UsePathBase("/foo");
// ...
app.UseRouting();
Catatan
Saat menggunakan WebApplication (lihat Migrasi dari ASP.NET Core di .NET 5 ke .NET 6), app.UseRouting harus dipanggil setelahnya UsePathBase sehingga middleware perutean dapat mengamati jalur yang dimodifikasi sebelum mencocokkan rute. Jika tidak, rute dicocokkan sebelum UsePathBase menulis ulang jalur seperti yang dijelaskan dalam ASP.NET Core Middleware dan Routing di ASP.NET Core.
Jalur asli dan dasar jalur diterapkan kembali ketika middleware dipanggil lagi secara terbalik. Untuk informasi selengkapnya tentang pemrosesan pesanan middleware, lihat ASP.NET Core Middleware.
Jika proksi memangkas jalur (misalnya, meneruskan /foo/api/1 ke /api/1), perbaiki pengalihan dan tautan dengan mengatur properti PathBase permintaan:
app.Use((context, next) =>
{
context.Request.PathBase = new PathString("/foo");
return next(context);
});
Jika proksi menambahkan data jalur, buang sebagian jalur untuk memperbaiki pengalihan dan tautan dengan menggunakan StartsWithSegments dan tetapkan ke properti Path:
app.Use((context, next) =>
{
if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
{
context.Request.Path = remainder;
}
return next(context);
});
Konfigurasi untuk proksi yang menggunakan nama header yang berbeda
Jika proksi tidak menggunakan header bernama X-Forwarded-For dan X-Forwarded-Proto untuk meneruskan alamat/port proksi dan informasi skema asal, atur ForwardedForHeaderName opsi dan ForwardedProtoHeaderName agar sesuai dengan nama header yang digunakan oleh proksi:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedForHeaderName = "HeaderNamUsedByProxy_X-Forwarded-For_Header";
options.ForwardedProtoHeaderName = "HeaderNamUsedByProxy_X-Forwarded-Proto_Header";
});
var app = builder.Build();
app.UseForwardedHeaders();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Teruskan skema untuk proksi terbalik Linux dan non-IIS
Aplikasi yang memanggil UseHttpsRedirection dan UseHsts menempatkan situs ke dalam perulangan tak terbatas jika disebarkan ke Azure Linux App Service, komputer virtual (VM) Azure Linux, atau di belakang proksi terbalik lainnya selain IIS. Proksi terbalik mengakhiri koneksi TLS, dan Kestrel tidak diberi tahu tentang skema permintaan yang benar. OAuth dan OIDC juga gagal dalam konfigurasi ini karena menghasilkan pengalihan yang salah. UseIISIntegration menambahkan dan mengonfigurasi Middleware Header yang Diteruskan saat berjalan di belakang IIS, tetapi tidak ada konfigurasi otomatis yang cocok untuk Linux (integrasi Apache atau Nginx).
Untuk meneruskan skema dari proksi dalam skenario non-IIS, aktifkan Middleware Header yang Diteruskan dengan mengatur ASPNETCORE_FORWARDEDHEADERS_ENABLED ke true. Peringatan: Bendera ini menggunakan pengaturan yang dirancang untuk lingkungan cloud dan tidak mengaktifkan fitur seperti KnownProxies option untuk membatasi penerus IP mana yang diterima.
Penerusan sertifikat
Azure
Untuk mengonfigurasi Azure App Service untuk penerusan sertifikat, lihat Mengonfigurasi autentikasi bersama TLS untuk Azure App Service. Panduan berikut berkaitan dengan mengonfigurasi aplikasi ASP.NET Core.
- Konfigurasikan Certificate Forwarding Middleware untuk menentukan nama header yang digunakan Azure. Tambahkan kode berikut untuk mengonfigurasi header tempat middleware membangun sertifikat.
- Panggil UseCertificateForwarding sebelum panggilan ke UseAuthentication.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
options.CertificateHeader = "X-ARR-ClientCert");
var app = builder.Build();
app.UseCertificateForwarding();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.UseAuthentication();
app.MapRazorPages();
app.Run();
Proksi web lainnya
Jika proksi yang digunakan bukan Perutean Permintaan Aplikasi (ARR) Azure App Service atau IIS, konfigurasikan proksi untuk meneruskan sertifikat yang diterimanya di header HTTP.
- Konfigurasikan Middleware Penerusan Sertifikat untuk menentukan nama header. Tambahkan kode berikut untuk mengonfigurasi header tempat middleware membangun sertifikat.
- Panggil UseCertificateForwarding sebelum panggilan ke UseAuthentication.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
options.CertificateHeader = "YOUR_CERTIFICATE_HEADER_NAME");
var app = builder.Build();
app.UseCertificateForwarding();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.UseAuthentication();
app.MapRazorPages();
app.Run();
Jika proksi tidak mengodekan sertifikat base64, seperti halnya dengan Nginx, atur opsi HeaderConverter. Pertimbangkan contoh berikut:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
{
options.CertificateHeader = "YOUR_CUSTOM_HEADER_NAME";
options.HeaderConverter = (headerValue) =>
{
// Conversion logic to create an X509Certificate2.
var clientCertificate = ConversionLogic.CreateAnX509Certificate2();
return clientCertificate;
};
});
var app = builder.Build();
app.UseCertificateForwarding();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.UseAuthentication();
app.MapRazorPages();
app.Run();
Pecahkan masalah
Ketika header tidak diteruskan seperti yang diharapkan, aktifkan tingkat debug dan pengelogan permintaan HTTP.
UseHttpLogging harus dipanggil setelah UseForwardedHeaders:
using Microsoft.AspNetCore.HttpLogging;
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddHttpLogging(options =>
{
options.LoggingFields = HttpLoggingFields.RequestPropertiesAndHeaders;
});
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
var app = builder.Build();
app.UseForwardedHeaders();
app.UseHttpLogging();
app.Use(async (context, next) =>
{
// Connection: RemoteIp
app.Logger.LogInformation("Request RemoteIp: {RemoteIpAddress}",
context.Connection.RemoteIpAddress);
await next(context);
});
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Jika ada beberapa nilai di header tertentu, Middleware Header yang Diteruskan memproses header dalam urutan terbalik dari kanan ke kiri. Nilai default ForwardLimit adalah 1 (satu), jadi hanya nilai paling kanan dari header-header yang diproses kecuali nilai ForwardLimit ditingkatkan.
IP remote asli dari permintaan harus cocok dengan entri dalam daftar KnownProxies atau KnownNetworks sebelum header yang diteruskan diproses. Ini membatasi spoofing header dengan tidak menerima penerus dari proksi yang tidak tepercaya. Ketika proksi yang tidak diketahui terdeteksi, pengelogan menunjukkan alamat proksi:
September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321
Dalam contoh sebelumnya, 10.0.0.100 adalah server proksi. Jika server adalah proksi tepercaya, tambahkan alamat IP server ke KnownProxies, atau tambahkan jaringan tepercaya ke KnownNetworks. Untuk informasi selengkapnya, lihat bagian Opsi Middleware Header yang Diteruskan.
using Microsoft.AspNetCore.HttpOverrides;
using System.Net;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseForwardedHeaders();
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Untuk menampilkan log, tambahkan "Microsoft.AspNetCore.HttpLogging": "Information" ke appsettings.Development.json file:
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.HttpLogging": "Information"
}
}
}
Penting
Hanya izinkan proksi dan jaringan tepercaya untuk meneruskan header. Jika tidak, serangan spoofing IP dimungkinkan .
Sumber Daya Tambahan:
Dalam konfigurasi yang direkomendasikan untuk ASP.NET Core, aplikasi dihosting menggunakan Modul IIS/ASP.NET Core, Nginx, atau Apache. Proxy server, load balancer, dan perangkat jaringan lainnya sering mengaburkan informasi tentang permintaan sebelum mencapai aplikasi.
- Ketika permintaan HTTPS diproksi melalui HTTP, skema asli (HTTPS) hilang dan harus diteruskan di header.
- Karena aplikasi menerima permintaan dari proksi dan bukan sumber sebenarnya di Internet atau jaringan perusahaan, alamat IP klien asal juga harus diteruskan di header.
Informasi ini mungkin penting dalam pemrosesan permintaan, misalnya dalam pengalihan, autentikasi, pembuatan tautan, evaluasi kebijakan, dan geolokasi klien.
Header yang diteruskan
Menurut konvensi, proksi meneruskan informasi di header HTTP.
| Kepala Halaman | Deskripsi |
|---|---|
| X-Forwarded-For | Menyimpan informasi tentang klien yang memulai permintaan dan proksi berikutnya dalam rantai proksi. Parameter ini mungkin berisi alamat IP (dan, secara opsional, nomor port). Dalam rantai server proksi, parameter pertama menunjukkan klien tempat permintaan pertama kali dibuat. Pengidentifikasi proksi berikutnya mengikuti. Proksi terakhir dalam rantai tidak ada dalam daftar parameter. Alamat IP proksi terakhir, dan secara opsional nomor port, tersedia sebagai alamat IP jarak jauh di lapisan transportasi. |
| X-Forwarded-Proto | Nilai skema asal (HTTP/HTTPS). Nilai mungkin juga merupakan daftar skema jika permintaan telah melintasi beberapa proksi. |
| X-Forwarded-Host | Nilai asli bidang header Host. Biasanya, proksi tidak mengubah header Host. Lihat Microsoft Security Advisory CVE-2018-0787 untuk informasi tentang kerentanan elevasi hak istimewa yang memengaruhi sistem di mana proksi tidak memvalidasi atau membatasi header Host ke nilai yang diketahui baik. |
Middleware Penerusan Header (ForwardedHeadersMiddleware) membaca header ini dan mengisi bidang terkait pada HttpContext.
Pembaruan middleware:
-
HttpContext.Connection.RemoteIpAddress: Diatur menggunakan nilai header
X-Forwarded-For. Pengaturan tambahan memengaruhi bagaimana middleware mengaturRemoteIpAddress. Untuk detailnya, lihat pengaturan Middleware Forwarded Headers. Nilai yang digunakan dihapus dariX-Forwarded-For, dan nilai lama dipertahankan dalamX-Original-For. Pola yang sama diterapkan ke header lain,HostdanProto. -
HttpContext.Request.Scheme: Atur
X-Forwarded-Protomenggunakan nilai header. -
HttpContext.Request.Host: Diatur menggunakan nilai
X-Forwarded-Hostheader.
Untuk informasi selengkapnya tentang sebelumnya, lihat masalah GitHub ini.
Pengaturan default Middleware Header yang Diteruskan dapat dikonfigurasi. Untuk pengaturan default:
- Hanya ada satu proksi antara aplikasi dan sumber permintaan.
- Hanya alamat loopback yang dikonfigurasi untuk proksi yang diketahui dan jaringan yang diketahui.
- Header yang diteruskan diberi nama
X-Forwarded-FordanX-Forwarded-Proto. - Nilai
ForwardedHeadersadalahForwardedHeaders.None; forwarder yang diinginkan harus diatur di sini untuk mengaktifkan middleware.
Tidak semua perangkat jaringan secara otomatis menambahkan header X-Forwarded-For dan X-Forwarded-Proto tanpa konfigurasi tambahan. Lihat panduan produsen perangkat Anda jika permintaan terproksi tidak berisi header ini ketika mencapai aplikasi. Jika perangkat menggunakan nama header yang berbeda dari X-Forwarded-For dan X-Forwarded-Proto, atur opsi ForwardedForHeaderName dan ForwardedProtoHeaderName agar sesuai dengan nama header yang digunakan oleh perangkat. Untuk informasi selengkapnya, lihat Opsi Middleware Header yang Diteruskan dan Konfigurasi untuk proksi yang menggunakan nama header yang berbeda.
Modul IIS/IIS Express dan ASP.NET Core
IIS Integration Middleware mengaktifkan Forwarded Headers Middleware secara default saat aplikasi dihosting out-of-process menggunakan IIS dan Modul ASP.NET Core. Middleware Header yang Diteruskan diaktifkan untuk dijalankan pertama kali dalam alur middleware dengan konfigurasi terbatas yang spesifik untuk Modul ASP.NET Core karena masalah kepercayaan terkait header yang diteruskan (contohnya, pemalsuan IP). Middleware dikonfigurasi untuk meneruskan header X-Forwarded-For dan X-Forwarded-Proto serta dibatasi hanya pada satu proxy localhost. Jika konfigurasi tambahan diperlukan, lihat opsi Middleware Header yang Diteruskan.
Skenario server proksi dan load balancer lainnya
Di luar penggunaan Integrasi IIS saat menghosting di luar proses, Middleware Header yang Diteruskan tidak diaktifkan secara default. Middleware "Forwarded Headers" harus diaktifkan agar aplikasi memproses header yang diteruskan dengan UseForwardedHeaders. Setelah mengaktifkan middleware, jika tidak ada ForwardedHeadersOptions yang ditentukan ke middleware, ForwardedHeadersOptions.ForwardedHeaders default adalah ForwardedHeaders.None.
Konfigurasikan middleware dengan ForwardedHeadersOptions untuk meneruskan header X-Forwarded-For dan X-Forwarded-Proto di Startup.ConfigureServices.
Urutan Middleware Header yang Diteruskan
Middleware Header yang Diteruskan harus dijalankan sebelum middleware lainnya. Urutan ini memastikan bahwa middleware yang mengandalkan informasi header yang diteruskan dapat memanfaatkan data header untuk pemrosesan. Middleware Penerusan Header dapat berjalan setelah proses diagnostik dan penanganan kesalahan, tetapi harus dijalankan terlebih dahulu sebelum memanggil UseHsts.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseForwardedHeaders();
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Atau, panggil UseForwardedHeaders sebelum diagnostik:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Catatan
Jika tidak ada ForwardedHeadersOptions yang ditentukan dalam Startup.ConfigureServices atau langsung ke metode ekstensi dengan UseForwardedHeaders, header default yang akan diteruskan adalah ForwardedHeaders.None. Properti ForwardedHeaders harus dikonfigurasi dengan header untuk diteruskan.
Konfigurasi Nginx
Untuk meneruskan X-Forwarded-For header dan X-Forwarded-Proto , lihat Host ASP.NET Core di Linux dengan Nginx.
Konfigurasi Apache
X-Forwarded-For ditambahkan secara otomatis (lihat Modul Apache mod_proxy: Header Permintaan Proksi Pembalik).
Opsi Middleware Header yang Diteruskan
ForwardedHeadersOptions mengontrol perilaku Middleware Header yang Diteruskan. Contoh berikut mengubah nilai default:
- Batasi jumlah entri di header yang diteruskan ke
2. - Tambahkan alamat proksi yang diketahui dari
127.0.10.1. - Ubah nama header yang diteruskan dari default
X-Forwarded-FormenjadiX-Forwarded-For-My-Custom-Header-Name.
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardLimit = 2;
options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});
| Opsi | Deskripsi |
|---|---|
| AllowedHosts | Membatasi host berdasarkan header X-Forwarded-Host ke nilai yang disediakan.
IList<string>. |
| ForwardedHeaders | Mengidentifikasi penerus mana yang harus diproses. Lihat ForwardedHeaders Enum untuk daftar bidang yang berlaku. Nilai umum yang ditetapkan ke properti ini adalah ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.Nilai defaultnya adalah ForwardedHeaders.None. |
| ForwardedForHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XForwardedForHeaderName. Opsi ini digunakan ketika proksi/penerus tidak menggunakan X-Forwarded-For header tetapi menggunakan beberapa header lain untuk meneruskan informasi.Default adalah X-Forwarded-For. |
| ForwardedHostHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XForwardedHostHeaderName. Opsi ini digunakan ketika proksi/penerus tidak menggunakan X-Forwarded-Host header tetapi menggunakan beberapa header lain untuk meneruskan informasi.Default adalah X-Forwarded-Host. |
| ForwardedProtoHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XForwardedProtoHeaderName. Opsi ini digunakan ketika proksi/penerus tidak menggunakan X-Forwarded-Proto header tetapi menggunakan beberapa header lain untuk meneruskan informasi.Default adalah X-Forwarded-Proto. |
| ForwardedPrefixHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XForwardedPrefixHeaderName. Opsi ini digunakan ketika proksi/penerus tidak menggunakan X-Forwarded-Prefix header tetapi menggunakan beberapa header lain untuk meneruskan informasi.Default adalah X-Forwarded-Prefix. |
| ForwardLimit | Membatasi jumlah entri dalam header yang diproses. Atur ke null untuk menonaktifkan batas, tetapi ini hanya boleh dilakukan jika KnownProxies atau KnownNetworks dikonfigurasi. Mengatur nilai selainnull adalah tindakan pencegahan (tetapi bukan jaminan) untuk melindungi dari proksi yang salah dikonfigurasi dan permintaan berbahaya yang tiba dari saluran samping di jaringan.Middleware Header yang diteruskan memproses header dalam urutan terbalik dari kanan ke kiri. Jika nilai default ( 1) digunakan, hanya nilai paling kanan dari header yang diproses kecuali nilai ForwardLimit ditingkatkan.Default adalah 1. |
| KnownNetworks | Rentang alamat jaringan yang diketahui untuk menerima header yang diteruskan. Berikan rentang IP menggunakan notasi Classless Interdomain Routing (CIDR). Jika server menggunakan soket mode ganda, alamat IPv4 disediakan dalam format IPv6 (misalnya, 10.0.0.1 dalam IPv4 yang diwakili dalam IPv6 sebagai ::ffff:10.0.0.1). Lihat IPAddress.MapToIPv6. Tentukan apakah format ini diperlukan dengan melihat HttpContext.Connection.RemoteIpAddress.Defaultnya adalah IList<IPNetwork> yang berisi satu entri untuk new IPNetwork(IPAddress.Loopback, 8). |
| KnownProxies | Alamat proksi yang diketahui untuk menerima header yang diteruskan. Gunakan KnownProxies untuk menentukan kecocokan alamat IP yang tepat.Jika server menggunakan soket mode ganda, alamat IPv4 disediakan dalam format IPv6 (misalnya, 10.0.0.1 dalam IPv4 yang diwakili dalam IPv6 sebagai ::ffff:10.0.0.1). Lihat IPAddress.MapToIPv6. Tentukan apakah format ini diperlukan dengan melihat HttpContext.Connection.RemoteIpAddress.Defaultnya adalah IList<IPAddress> yang berisi satu entri untuk IPAddress.IPv6Loopback. |
| OriginalForHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XOriginalForHeaderName. Default adalah X-Original-For. |
| OriginalHostHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XOriginalHostHeaderName. Default adalah X-Original-Host. |
| OriginalProtoHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XOriginalProtoHeaderName. Default adalah X-Original-Proto. |
| OriginalPrefixHeaderName | Gunakan header yang ditentukan oleh properti ini alih-alih yang ditentukan oleh ForwardedHeadersDefaults.XOriginalPrefixHeaderName. Default adalah X-Original-Prefix. |
| RequireHeaderSymmetry | Mengharuskan jumlah nilai header selaras dengan ForwardedHeadersOptions.ForwardedHeaders yang sedang diproses. Default dalam ASP.NET Core 1.x adalah true. Default dalam ASP.NET Core 2.0 atau yang lebih baru adalah false. |
Skenario dan kasus penggunaan
Ketika tidak dimungkinkan untuk menambahkan header yang diteruskan serta semua permintaan telah aman
Dalam beberapa kasus, mungkin tidak mungkin untuk menambahkan header yang diteruskan ke permintaan yang diproksikan ke aplikasi. Jika proksi memastikan bahwa semua permintaan eksternal publik adalah HTTPS, skema dapat diatur Startup.Configure secara manual sebelum menggunakan jenis middleware apa pun.
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
Kode ini dapat dinonaktifkan dengan variabel lingkungan atau pengaturan konfigurasi lainnya dalam lingkungan pengembangan atau penahapan.
Menangani basis jalur dan proksi yang mengubah jalur permintaan
Beberapa proxy melewati path secara utuh tetapi dengan path dasar aplikasi yang harus dihapus supaya perutean berfungsi dengan baik. Middleware UsePathBaseExtensions.UsePathBase membagi jalur menjadi HttpRequest.Path dan jalur dasar aplikasi ke HttpRequest.PathBase.
Jika /foo adalah jalur dasar aplikasi untuk jalur proksi yang diteruskan sebagai /foo/api/1, middleware mengatur Request.PathBase ke /foo dan Request.Path ke /api/1 dengan perintah berikut:
app.UsePathBase("/foo");
Jalur asli dan dasar jalur diterapkan kembali ketika middleware dipanggil lagi secara terbalik. Untuk informasi selengkapnya tentang pemrosesan pesanan middleware, lihat ASP.NET Core Middleware.
Jika proksi memangkas jalur (misalnya, meneruskan /foo/api/1 ke /api/1), perbaiki pengalihan dan tautan dengan mengatur properti PathBase permintaan:
app.Use((context, next) =>
{
context.Request.PathBase = new PathString("/foo");
return next();
});
Jika proksi menambahkan data jalur, buang sebagian jalur untuk memperbaiki pengalihan dan tautan dengan menggunakan StartsWithSegments dan tetapkan ke properti Path:
app.Use((context, next) =>
{
if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
{
context.Request.Path = remainder;
}
return next();
});
Konfigurasi untuk proksi yang menggunakan nama header yang berbeda
Jika proksi tidak menggunakan header bernama X-Forwarded-For dan X-Forwarded-Proto untuk meneruskan alamat/port proksi dan informasi skema asal, atur ForwardedForHeaderName opsi dan ForwardedProtoHeaderName agar sesuai dengan nama header yang digunakan oleh proksi:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedForHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-For_Header";
options.ForwardedProtoHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-Proto_Header";
});
Teruskan skema untuk proksi terbalik Linux dan non-IIS
Aplikasi yang memanggil UseHttpsRedirection dan UseHsts menempatkan situs ke dalam perulangan tak terbatas jika disebarkan ke Azure Linux App Service, komputer virtual (VM) Azure Linux, atau di belakang proksi terbalik lainnya selain IIS. Proksi terbalik mengakhiri TLS, dan Kestrel tidak mengetahui skema permintaan yang benar. OAuth dan OIDC juga gagal dalam konfigurasi ini karena menghasilkan pengalihan yang salah. UseIISIntegration menambahkan dan mengonfigurasi Middleware Header yang Diteruskan saat berjalan di belakang IIS, tetapi tidak ada konfigurasi otomatis yang cocok untuk Linux (integrasi Apache atau Nginx).
Untuk meneruskan skema dari proksi dalam skenario non-IIS, tambahkan dan konfigurasikan Forwarded Headers Middleware. Di Startup.ConfigureServices, gunakan kode berikut:
// using Microsoft.AspNetCore.HttpOverrides;
if (string.Equals(
Environment.GetEnvironmentVariable("ASPNETCORE_FORWARDEDHEADERS_ENABLED"),
"true", StringComparison.OrdinalIgnoreCase))
{
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto;
// Only loopback proxies are allowed by default.
// Clear that restriction because forwarders are enabled by explicit
// configuration.
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
}
Penerusan sertifikat
Azure
Untuk mengonfigurasi Azure App Service untuk penerusan sertifikat, lihat Mengonfigurasi autentikasi bersama TLS untuk Azure App Service. Panduan berikut berkaitan dengan mengonfigurasi aplikasi ASP.NET Core.
Di Startup.Configure, tambahkan kode berikut sebelum panggilan ke app.UseAuthentication();:
app.UseCertificateForwarding();
Konfigurasikan Middleware Penerusan Sertifikat untuk menentukan nama header yang digunakan Azure. Di Startup.ConfigureServices, tambahkan kode berikut untuk mengonfigurasi header tempat middleware membangun sertifikat:
services.AddCertificateForwarding(options =>
options.CertificateHeader = "X-ARR-ClientCert");
Proksi web lainnya
Jika proksi yang digunakan bukan Perutean Permintaan Aplikasi (ARR) Azure App Service atau IIS, konfigurasikan proksi untuk meneruskan sertifikat yang diterimanya di header HTTP. Di Startup.Configure, tambahkan kode berikut sebelum panggilan ke app.UseAuthentication();:
app.UseCertificateForwarding();
Konfigurasikan Middleware Penerusan Sertifikat untuk menentukan nama header. Di Startup.ConfigureServices, tambahkan kode berikut untuk mengonfigurasi header tempat middleware membangun sertifikat:
services.AddCertificateForwarding(options =>
options.CertificateHeader = "YOUR_CERTIFICATE_HEADER_NAME");
Jika proksi tidak mengodekan sertifikat base64 (seperti halnya dengan Nginx), atur HeaderConverter opsi . Pertimbangkan contoh berikut di Startup.ConfigureServices:
services.AddCertificateForwarding(options =>
{
options.CertificateHeader = "YOUR_CUSTOM_HEADER_NAME";
options.HeaderConverter = (headerValue) =>
{
var clientCertificate =
/* some conversion logic to create an X509Certificate2 */
return clientCertificate;
}
});
Pecahkan masalah
Saat header tidak diteruskan seperti yang diharapkan, aktifkan pengelogan. Jika log tidak memberikan informasi yang memadai untuk memecahkan masalah, hitung header permintaan yang diterima oleh server. Gunakan middleware sebaris untuk menulis header permintaan ke respons aplikasi atau mencatat header.
Untuk menulis header ke respons aplikasi, letakkan middleware terminal sebaris berikut segera setelah panggilan ke UseForwardedHeaders di Startup.Configure:
app.Run(async (context) =>
{
context.Response.ContentType = "text/plain";
// Request method, scheme, and path
await context.Response.WriteAsync(
$"Request Method: {context.Request.Method}{Environment.NewLine}");
await context.Response.WriteAsync(
$"Request Scheme: {context.Request.Scheme}{Environment.NewLine}");
await context.Response.WriteAsync(
$"Request Path: {context.Request.Path}{Environment.NewLine}");
// Headers
await context.Response.WriteAsync($"Request Headers:{Environment.NewLine}");
foreach (var header in context.Request.Headers)
{
await context.Response.WriteAsync($"{header.Key}: " +
$"{header.Value}{Environment.NewLine}");
}
await context.Response.WriteAsync(Environment.NewLine);
// Connection: RemoteIp
await context.Response.WriteAsync(
$"Request RemoteIp: {context.Connection.RemoteIpAddress}");
});
Anda dapat menulis ke log alih-alih isi respons. Menulis ke log memungkinkan situs berfungsi secara normal selama debugging.
Untuk menulis log daripada ke isi respons:
- Masukkan
ILogger<Startup>ke dalam kelasStartupseperti yang dijelaskan dalam Membuat pesan log. - Tempatkan middleware sebaris berikut segera setelah panggilan ke UseForwardedHeaders di
Startup.Configure.
app.Use(async (context, next) =>
{
// Request method, scheme, path, and base path
_logger.LogDebug("Request Method: {Method}", context.Request.Method);
_logger.LogDebug("Request Scheme: {Scheme}", context.Request.Scheme);
_logger.LogDebug("Request Path: {Path}", context.Request.Path);
_logger.LogDebug("Request Path Base: {PathBase}", context.Request.PathBase);
// Headers
foreach (var header in context.Request.Headers)
{
_logger.LogDebug("Header: {Key}: {Value}", header.Key, header.Value);
}
// Connection: RemoteIp
_logger.LogDebug("Request RemoteIp: {RemoteIpAddress}",
context.Connection.RemoteIpAddress);
await next();
});
Saat diproses, X-Forwarded-{For|Proto|Host|Prefix} nilai dipindahkan ke X-Original-{For|Proto|Host|Prefix}. Jika ada beberapa nilai di header tertentu, Middleware Header yang Diteruskan memproses header dalam urutan terbalik dari kanan ke kiri. Nilai default ForwardLimit adalah 1 (satu), jadi hanya nilai paling kanan dari header-header yang diproses kecuali nilai ForwardLimit ditingkatkan.
IP remote asli dari permintaan harus cocok dengan entri dalam daftar KnownProxies atau KnownNetworks sebelum header yang diteruskan diproses. Ini membatasi spoofing header dengan tidak menerima penerus dari proksi yang tidak tepercaya. Ketika proksi yang tidak diketahui terdeteksi, pengelogan menunjukkan alamat proksi:
September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321
Dalam contoh sebelumnya, 10.0.0.100 adalah server proksi. Jika server adalah proksi tepercaya, tambahkan alamat IP server ke KnownProxies (atau tambahkan jaringan tepercaya ke KnownNetworks) di Startup.ConfigureServices. Untuk informasi selengkapnya, lihat bagian Opsi Middleware Header yang Diteruskan.
services.Configure<ForwardedHeadersOptions>(options =>
{
options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});
Penting
Hanya izinkan proksi dan jaringan tepercaya untuk meneruskan header. Jika tidak, serangan spoofing IP dimungkinkan .
Sumber Daya Tambahan:
ASP.NET Core