Skip to Content
DocumentationバックエンドランタイムASP.NET Core (C#)

C#(ASP.NET Core)

ASP.NET Core アプリケーションは、ミドルウェアコンポーネントのパイプラインを通じて受信 HTTP リクエストを処理します。ProxyTracer ミドルウェアをパイプラインに追加することで、リクエストがコントローラーやエンドポイントに到達する前にクライアント IP アドレスを自動検証し、VPN やプロキシトラフィックを遮断できます。

ミドルウェアの実装

このミドルウェアは HttpContext からクライアント IP アドレスを読み取り、ProxyTracer API に高速な HTTP クエリを実行して、接続がプロキシまたは VPN としてフラグ付けされた場合に即座に 403 Forbidden JSON レスポンスを返します。

using System; using System.Net.Http; using System.Net.Http.Headers; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace ProxyTracer.Security { public class ProxyTracerMiddleware { private readonly RequestDelegate _next; private readonly HttpClient _httpClient; private readonly ILogger<ProxyTracerMiddleware> _logger; private readonly string _apiKey; public ProxyTracerMiddleware(RequestDelegate next, IConfiguration config, ILogger<ProxyTracerMiddleware> logger) { _next = next; _logger = logger; _apiKey = config["PROXYTRACER_API_KEY"] ?? throw new ArgumentNullException("PROXYTRACER_API_KEY is missing"); // 厳格な500msのタイムアウトを持つ再利用可能なクライアント _httpClient = new HttpClient { Timeout = TimeSpan.FromMilliseconds(500) }; } public async Task InvokeAsync(HttpContext context) { // 1. IPを抽出 (Program.csでapp.UseForwardedHeaders()の設定が必要です) var ip = context.Connection.RemoteIpAddress?.ToString(); // ローカル開発環境のIPをスキップ if (!string.IsNullOrEmpty(ip) && ip != "127.0.0.1" && ip != "::1") { try { // 2. ProxyTracer APIに非同期でクエリを実行 using var request = new HttpRequestMessage(HttpMethod.Get, $"https://api.proxytracer.com/v1/check/{ip}"); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey); using var response = await _httpClient.SendAsync(request); if (response.IsSuccessStatusCode) { using var jsonStream = await response.Content.ReadAsStreamAsync(); var ptResponse = await JsonSerializer.DeserializeAsync<ProxyTracerResult>(jsonStream); // 3. プロキシ/VPNが検出された場合は接続を切断 if (ptResponse != null && ptResponse.Proxy) { context.Response.StatusCode = StatusCodes.Status403Forbidden; context.Response.ContentType = "application/json"; await context.Response.WriteAsync("{\"error\": \"Access Denied: VPN or Proxy detected.\"}"); return; // リクエストパイプラインをショートサーキット(即時終了) } } } catch (Exception ex) { // フェイルオープン: エラーをログに記録し、リクエストの通過を許可 _logger.LogWarning($"ProxyTracer validation failed: {ex.Message}"); } } // 4. トラフィックは正常です。コントローラーへ処理を渡します await _next(context); } // {"proxy": true|false} レスポンスに正確にマッピングする軽量な構造体 private class ProxyTracerResult { [JsonPropertyName("proxy")] public bool Proxy { get; set; } } } }

設定:

設定時の注意: このミドルウェアは、リクエストパイプラインの早い段階(Program.cs 内の app.UseRouting() の直後、または認証・認可ミドルウェアの前)に登録してください。

var app = builder.Build(); // 1. NGINX/Cloudflareロードバランサーの背後にある場合、実際のIPが抽出されることを確認 app.UseForwardedHeaders(); // 2. 悪意あるトラフィックを早期に遮断 app.UseMiddleware<ProxyTracer.Security.ProxyTracerMiddleware>(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
最終更新日: