NextQuantumSystem.Protect.SwaggerGuard 1.0.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package NextQuantumSystem.Protect.SwaggerGuard --version 1.0.2
                    
NuGet\Install-Package NextQuantumSystem.Protect.SwaggerGuard -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NextQuantumSystem.Protect.SwaggerGuard" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NextQuantumSystem.Protect.SwaggerGuard" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="NextQuantumSystem.Protect.SwaggerGuard" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NextQuantumSystem.Protect.SwaggerGuard --version 1.0.2
                    
#r "nuget: NextQuantumSystem.Protect.SwaggerGuard, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NextQuantumSystem.Protect.SwaggerGuard@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NextQuantumSystem.Protect.SwaggerGuard&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=NextQuantumSystem.Protect.SwaggerGuard&version=1.0.2
                    
Install as a Cake Tool

NextQuantumSystem.Protect — SwaggerGuard

🌐 Language / Dil: English (below) · Türkçe

Puts Swagger UI and related endpoints behind a JWT + role gate — a reusable protection module you can drop into any project as a DLL.

Version 1.0.2
Date 2026-07-18
Target Frameworks .NET 8 · 9 · 10 (net8.0, net9.0, net10.0)
ABP per-TFM: 8.3.4 / 9.3.7 / 10.5.0 (optional — plain ASP.NET Core is also supported)
Status Core + ABP wrapper + 10 integration tests (10/10 passing)

⚡ Quick Start (TL;DR)

ABP host — 3 steps:

// 1) Add package:   dotnet add package NextQuantumSystem.Protect.SwaggerGuard.Abp
// 2) Depend on the module:
[DependsOn(typeof(ProtectSwaggerGuardModule))]
public class MyHttpApiHostModule : AbpModule { }
// 3) Add the "Swagger" section to appsettings.json (below). Middleware wires up automatically.

Plain ASP.NET Core host — 3 steps:

// 1) Add package:   dotnet add package NextQuantumSystem.Protect.SwaggerGuard
// 2) Program.cs:
builder.Services.AddSwaggerProtection(builder.Configuration);
app.UseSwaggerProtection();   // ← BEFORE app.UseSwaggerUI()
// 3) Add the "Swagger" section to appsettings.json (below).

Minimal appsettings.json:

{
  "Swagger": {
    "ProtectedPaths": [ "swagger", "swagger/v1/swagger.json" ],
    "AllowedRoles": [ "admin" ],
    "Authority": "https://id.example.com"   // ← the IdP that issues the token; REQUIRED
  }
}

Result: everyone hitting /swagger first sees a token-input page → only a valid JWT with the admin role gets in.


1. Purpose — Why & What For

Problem

In ABP / ASP.NET Core projects the Swagger UI (/swagger) is often publicly open. On dev/staging this leaks your API schema, endpoint list and example payloads to unauthorized people.

Solution

Swagger no longer opens directly. Instead a token-input page appears; the user pastes a valid JWT, the token's signature + issuer + expiry are verified, and only users with an allowed role (AllowedRoles) can reach Swagger.

Why a separate module / DLL?

Instead of copy-pasting the same protection into dozens of microservices, you drop one DLL into every project for consistent, defense-in-depth protection (each service protects itself; you don't rely on the gateway alone). Each project only changes values in its own appsettings.json; the code and the DLL stay identical — no rebuild needed.


2. How It Works — Flow

Request  ──▶  SwaggerProtectionMiddleware
                │
                ├─ IsEnabled=false?  ──▶ pass through
                │
                ├─ Path == TokenInputPath (auth/swagger)?
                │     ├─ GET  ──▶ show token-input page (200)
                │     └─ POST ──▶ validate token
                │                   ├─ invalid/expired ──▶ page + 401
                │                   ├─ role not allowed ──▶ page + 403
                │                   └─ valid + role OK ──▶ set cookie + 302 to returnUrl
                │
                ├─ Path not in ProtectedPaths? ──▶ pass through
                │
                └─ Protected path:
                      ├─ no cookie        ──▶ 302 to login
                      ├─ invalid cookie   ──▶ clear cookie + 302 to login
                      ├─ role not allowed ──▶ 403
                      └─ all OK           ──▶ pass to Swagger

Cookie: the validated token is written as __auth_token, HttpOnly + Secure (on HTTPS) + SameSite=Lax, valid for CookieExpirationHours.


3. Architecture

Decision: the core is ABP-independent, so both ABP and plain ASP.NET Core hosts can use it. The ABP side is a thin wrapper.

Protect/
├── src/
│   ├── NextQuantumSystem.Protect.SwaggerGuard/          ← ABP-free core
│   │   ├── SwaggerProtectionOptions.cs                  · all settings
│   │   ├── SwaggerProtectionMiddleware.cs               · path/cookie/role/redirect logic
│   │   ├── SwaggerProtectionExtensions.cs               · AddSwaggerProtection / UseSwaggerProtection
│   │   └── Internal/
│   │       ├── IJwtTokenValidator.cs                    · validation abstraction
│   │       ├── JwksJwtTokenValidator.cs                 · signature validation via Authority/JWKS
│   │       └── TokenInputPageRenderer.cs                · token-input page (HTML)
│   │
│   └── NextQuantumSystem.Protect.SwaggerGuard.Abp/      ← thin ABP module
│       └── ProtectSwaggerGuardModule.cs                 · AbpModule, automatic wiring
│
└── test/
    └── NextQuantumSystem.Protect.SwaggerGuard.Tests/    ← in-memory TestServer, 10 tests
Layer Dependency Purpose
SwaggerGuard Microsoft.AspNetCore.App, Microsoft.IdentityModel.* Framework-agnostic core. Plain ASP.NET Core hosts consume this directly.
SwaggerGuard.Abp Volo.Abp.AspNetCore + core Automatic wiring for ABP hosts.

4. Setup & Usage

4.a) ABP Host

1. Add the package:

dotnet add package NextQuantumSystem.Protect.SwaggerGuard.Abp

2. Depend on the module:

[DependsOn(
    typeof(ProtectSwaggerGuardModule)   // ← one line, everything else is automatic
    // ... your other modules
)]
public class MyServiceHttpApiHostModule : AbpModule { }

3. Add the "Swagger" section to appsettings.json (see Configuration).

Because the module is a dependency of the host, its middleware registers before the host's own UseAbpSwaggerUI() call (ABP init order: dependencies first). No extra Use... call needed.

4.b) Plain ASP.NET Core Host

1. Add the package:

dotnet add package NextQuantumSystem.Protect.SwaggerGuard

2. Program.cs:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwaggerProtection(builder.Configuration);   // binds the "Swagger" section

var app = builder.Build();
app.UseSwaggerProtection();   // ← BEFORE Swagger UI
app.UseSwagger();
app.UseSwaggerUI();
app.Run();

Alternative registration methods:

services.AddSwaggerProtection(builder.Configuration.GetSection("Swagger"));  // specific section
services.AddSwaggerProtection(o =>                                            // in code
{
    o.Authority = "https://id.example.com";
    o.ProtectedPaths = new() { "swagger", "swagger/v1/swagger.json" };
    o.AllowedRoles   = new() { "admin" };
});

4.c) NuGet Distribution

Two packages are produced:

Package When to use Dependencies
NextQuantumSystem.Protect.SwaggerGuard Plain ASP.NET Core host Microsoft.IdentityModel.*
NextQuantumSystem.Protect.SwaggerGuard.Abp ABP host ↑ core + Volo.Abp.AspNetCore

When you install the ABP package the core comes in automatically (declared as a dependency). On an ABP host you only need the .Abp package.

Build the packages (two .nupkg under ./artifacts):

dotnet pack NextQuantumSystem.Protect.slnx -c Release -o ./artifacts

Push to public nuget.org:

dotnet nuget push "artifacts/*.nupkg" --source https://api.nuget.org/v3/index.json --api-key <NUGET_API_KEY> --skip-duplicate

⚠️ A version published to nuget.org cannot be deleted (only "unlisted") and the package ID is reserved globally.

With .github/workflows/build.yml:

  • Every push/PR → build + test + pack (uploaded as artifacts).
  • On GitHub Release → auto-push to nuget.org.

Publishing uses NuGet Trusted Publishing (OIDC) — no long-lived API key secret is stored; a short-lived key is obtained via the production environment.

Releasing a new version:

# 1) Bump <Version> in the csproj files (e.g. 1.0.2), commit + push
# 2) Create a GitHub Release for that version (tag: v1.0.2)
#    → build.yml packs + pushes automatically

5. Configuration Reference

The "Swagger" section in appsettings.json binds to SwaggerProtectionOptions.

{
  "Swagger": {
    "IsEnabled": true,
    "RoutePrefix": "swagger",
    "DocumentTitle": "API Docs",
    "CookieName": "__auth_token",
    "CookieExpirationHours": 8,
    "TokenInputPath": "auth/swagger",
    "ProtectedPaths": [ "swagger", "api/abp/api-definition", "swagger/v1/swagger.json" ],
    "AllowedRoles": [ "admin" ],
    "Authority": "https://id.example.com",
    "Audience": "my-service",
    "ValidateAudience": false,
    "ValidateIssuer": true,
    "RequireHttpsMetadata": true,
    "RoleClaimTypes": [ "role", "roles" ]
  }
}
Setting Type Default Description
IsEnabled bool true If false the middleware does nothing (protection off).
RoutePrefix string "swagger" Informational; used as the returnUrl fallback.
DocumentTitle string "API Dokümanı" <title> of the token-input page.
CookieName string "__auth_token" Cookie holding the validated JWT.
CookieExpirationHours int 8 Cookie lifetime (hours).
TokenInputPath string "auth/swagger" Path of the token-input page. Must never be inside ProtectedPaths (infinite redirect).
ProtectedPaths string[] [] Path prefixes (no leading slash) to protect.
AllowedRoles string[] [] Allowed roles. Empty: any validated token is accepted (no role restriction).
Authority string? null The OpenID/OAuth authority issuing tokens; JWKS is fetched from it. Required for validation.
Audience string? null Expected audience (required when ValidateAudience=true).
ValidateAudience bool false Validate the audience?
ValidateIssuer bool true Validate the issuer (from the Authority)?
RequireHttpsMetadata bool true Require HTTPS for authority metadata? (false in dev).
RoleClaimTypes string[] ["role","roles",".../role"] Claim types to read roles from (IdPs differ).

📄 Full example + annotated scenarios: samples/appsettings.Swagger.sample.jsonc — every option explained inline plus 5 ready scenarios (production, development, no-role, audience-validated, disabled).

Values that differ per project (Authority, Audience) live in each host's own config, not in the DLL. To reduce repetition: a shared appsettings.shared.json, environment variables (Swagger__Authority=...), or the in-code AddSwaggerProtection(o => ...) overload.


6. Security Notes

  • 🔴 The JWT signature is always verified. If Authority is not configured, validation fails — a token is never accepted by "just decoding" it. Signature + issuer + expiry are always checked. This stops an attacker from forging their own role=admin token.
  • 🔁 Infinite-redirect guard: TokenInputPath is never protected; it is handled on its own.
  • 🍪 Cookie: HttpOnly (JS can't read it) + Secure (on HTTPS) + SameSite=Lax. Stale/invalid cookies are cleared automatically.
  • ↩️ Open-redirect guard: returnUrl allows only local (same-site) paths; // or absolute URLs are rejected.
  • ⚠️ Protecting api/abp/api-definition may affect ABP dynamic client-proxy generation (tools calling without a cookie get 302). Make it a conscious choice.
  • 🌐 Gateway/reverse-proxy: X-Forwarded-* / PathBase can change the perceived path; tune ProtectedPaths accordingly.

7. Tests

10 integration tests over real HTTP on an in-memory TestServer (test/NextQuantumSystem.Protect.SwaggerGuard.Tests). A symmetric-key validator is injected instead of JWKS so the full middleware logic is exercised without a live authority.

dotnet test NextQuantumSystem.Protect.slnx
Scenario Expected
Unprotected path (/healthz) 200 (passes)
Protected path, no cookie 302 → /auth/swagger?returnUrl=...
Login page GET 200 + HTML
POST valid admin token 302 + Set-Cookie
POST valid non-admin token 403
POST invalid token 401
POST expired token 401
Protected path + valid admin cookie 200 (passes)
Protected path + non-admin cookie 403
Protected path + garbage cookie 302 + cookie cleared

Result: 10/10 passing.


8. FAQ

Q: Is this an ABP module or a plain library? Both. The core (SwaggerGuard) is an ABP-free plain library; SwaggerGuard.Abp is a thin module that auto-wires it for ABP hosts.

Q: Do I need a separate DLL per microservice? No. The same DLL is used everywhere; only appsettings.json changes.

Q: Does NuGet support multi-language READMEs? NuGet shows a single README per package. The convention (used here) is one README with language sections and a selector at the top.


9. Version History

1.0.2 — 2026-07-18

  • Multi-targeting: supports net8.0, net9.0, net10.0. More projects can now consume the package.
  • The ABP package references the matching ABP major per framework (net8.0→8.3.4, net9.0→9.3.7, net10.0→10.5.0).
  • Tests run on all three frameworks — 10/10 passing on each.
  • Note: net6.0/net7.0 are intentionally not targeted (out of support & dropped by ABP); the floor is net8.0 (LTS).

1.0.1 — 2026-07-18

  • Multilingual README (English + Türkçe) with a language selector at the top.

1.0.0 — 2026-07-18

  • First release.
  • SwaggerProtectionMiddleware: path matching, cookie-based JWT gate, role check, redirect flow.
  • JwksJwtTokenValidator: signature + issuer + expiry validation via Authority/JWKS.
  • Token-input page (no MVC, HTML rendered).
  • AddSwaggerProtection / UseSwaggerProtection extensions for plain ASP.NET Core.
  • ProtectSwaggerGuardModule for ABP hosts (automatic wiring via a single [DependsOn]).
  • 10 integration tests (in-memory TestServer).
  • NuGet packaging: SwaggerGuard (plain) and SwaggerGuard.Abp (ABP) via dotnet pack.
  • Annotated sample config: samples/appsettings.Swagger.sample.jsonc.


<a name="-türkçe"></a>

🇹🇷 Türkçe

🌐 Language / Dil: English · Türkçe (aşağıda)

Swagger UI'yi ve ilişkili endpoint'leri JWT + rol geçidinin arkasına alan, DLL olarak her projeye takılabilen yeniden kullanılabilir koruma modülü.

Sürüm 1.0.2
Tarih 2026-07-18
Hedef Framework'ler .NET 8 · 9 · 10 (net8.0, net9.0, net10.0)
ABP TFM'e göre: 8.3.4 / 9.3.7 / 10.5.0 (opsiyonel — düz ASP.NET Core da desteklenir)
Durum Çekirdek + ABP sarmalayıcı + 10 integration testi (10/10 geçiyor)

⚡ Nasıl Kullanılır — Özet (TL;DR)

ABP host'ta 3 adım:

// 1) Paketi ekle:   dotnet add package NextQuantumSystem.Protect.SwaggerGuard.Abp
// 2) Modülü bağla:
[DependsOn(typeof(ProtectSwaggerGuardModule))]
public class MyHttpApiHostModule : AbpModule { }
// 3) appsettings.json'a "Swagger" bölümünü ekle (aşağıda). Middleware otomatik devreye girer.

Düz ASP.NET Core host'ta 3 adım:

// 1) Paketi ekle:   dotnet add package NextQuantumSystem.Protect.SwaggerGuard
// 2) Program.cs:
builder.Services.AddSwaggerProtection(builder.Configuration);
app.UseSwaggerProtection();   // ← app.UseSwaggerUI()'DEN ÖNCE
// 3) appsettings.json'a "Swagger" bölümünü ekle (aşağıda).

Minimum appsettings.json:

{
  "Swagger": {
    "ProtectedPaths": [ "swagger", "swagger/v1/swagger.json" ],
    "AllowedRoles": [ "admin" ],
    "Authority": "https://id.example.com"   // ← token'ı üreten IdP; ZORUNLU
  }
}

Sonuç: /swagger'a giden herkes önce token giriş sayfasını görür → geçerli JWT + admin rolü olan girer, olmayan giremez.


1. Amaç — Neden & Niçin

Problem

ABP / ASP.NET Core projelerinde Swagger UI (/swagger) çoğu zaman herkese açık gelir. Development/staging ortamlarında bu, API şemasının, endpoint listesinin ve örnek payload'ların yetkisiz kişilere sızması demektir.

Çözüm

Swagger direkt açılmaz. Yerine token giriş sayfası çıkar; kullanıcı geçerli bir JWT girer, token imzası + issuer + expiry doğrulanır ve yalnızca izin verilen rollere (AllowedRoles) sahip kullanıcılar Swagger'a erişebilir.

Neden ayrı bir modül / DLL?

Aynı korumayı onlarca mikroservise kopyala-yapıştır yapmak yerine, tek bir DLL'i her projeye takıp her serviste tutarlı koruma sağlanır (defense-in-depth: her servis kendini korur, sadece gateway'e güvenilmez). Her proje sadece kendi appsettings.json'ındaki değerleri değiştirir; kod ve DLL aynı kalır, yeniden derleme gerekmez.


2. Nasıl Çalışır — Akış

İstek  ──▶  SwaggerProtectionMiddleware
                │
                ├─ IsEnabled=false?  ──▶ dokunma, geç
                │
                ├─ Yol == TokenInputPath (auth/swagger)?
                │     ├─ GET  ──▶ token giriş sayfasını göster (200)
                │     └─ POST ──▶ token doğrula
                │                   ├─ geçersiz/expired ──▶ sayfa + 401
                │                   ├─ rol uygun değil   ──▶ sayfa + 403
                │                   └─ geçerli+rol OK ──▶ cookie yaz + returnUrl'e 302
                │
                ├─ Yol ProtectedPaths içinde değil? ──▶ geç
                │
                └─ Korunan yol:
                      ├─ cookie yok       ──▶ giriş sayfasına 302
                      ├─ cookie geçersiz  ──▶ cookie sil + giriş sayfasına 302
                      ├─ rol uygun değil  ──▶ 403
                      └─ her şey OK       ──▶ Swagger'a geç

Cookie: doğrulanan token __auth_token adıyla, HttpOnly + Secure (HTTPS'te) + SameSite=Lax + CookieExpirationHours süreli olarak yazılır.


3. Mimari

Karar: çekirdek ABP'den bağımsız, böylece hem ABP hem düz ASP.NET Core host'lar kullanabilir. ABP tarafı ince bir sarmalayıcıdır.

Protect/
├── src/
│   ├── NextQuantumSystem.Protect.SwaggerGuard/          ← ABP'siz düz çekirdek
│   │   ├── SwaggerProtectionOptions.cs                  · tüm ayarlar
│   │   ├── SwaggerProtectionMiddleware.cs               · path/cookie/rol/redirect mantığı
│   │   ├── SwaggerProtectionExtensions.cs               · AddSwaggerProtection / UseSwaggerProtection
│   │   └── Internal/
│   │       ├── IJwtTokenValidator.cs                    · doğrulama soyutlaması
│   │       ├── JwksJwtTokenValidator.cs                 · Authority/JWKS ile imza doğrulama
│   │       └── TokenInputPageRenderer.cs                · token giriş sayfası (HTML)
│   │
│   └── NextQuantumSystem.Protect.SwaggerGuard.Abp/      ← ince ABP modülü
│       └── ProtectSwaggerGuardModule.cs                 · AbpModule, otomatik wiring
│
└── test/
    └── NextQuantumSystem.Protect.SwaggerGuard.Tests/    ← in-memory TestServer, 10 test
Katman Bağımlılık Amaç
SwaggerGuard Microsoft.AspNetCore.App, Microsoft.IdentityModel.* Framework-agnostik çekirdek. Düz ASP.NET Core host'lar buna doğrudan takılır.
SwaggerGuard.Abp Volo.Abp.AspNetCore + çekirdek ABP host'ları için otomatik wiring.

4. Kurulum & Kullanım

4.a) ABP Host

1. Paketi ekle:

dotnet add package NextQuantumSystem.Protect.SwaggerGuard.Abp

2. Modülü bağımlılık olarak ekle:

[DependsOn(
    typeof(ProtectSwaggerGuardModule)   // ← tek satır, gerisi otomatik
    // ... diğer modülleriniz
)]
public class MyServiceHttpApiHostModule : AbpModule { }

3. appsettings.json'a "Swagger" bölümünü ekle (bkz. Konfigürasyon).

Middleware, modül host'un bağımlılığı olduğu için host'un kendi UseAbpSwaggerUI() çağrısından önce kaydolur (ABP init sırası: bağımlılıklar önce). Ekstra bir Use... çağrısı gerekmez.

4.b) Düz ASP.NET Core Host

1. Paketi ekle:

dotnet add package NextQuantumSystem.Protect.SwaggerGuard

2. Program.cs:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwaggerProtection(builder.Configuration);   // "Swagger" bölümünden bind eder

var app = builder.Build();
app.UseSwaggerProtection();   // ← Swagger UI'DEN ÖNCE
app.UseSwagger();
app.UseSwaggerUI();
app.Run();

Alternatif kayıt yöntemleri:

services.AddSwaggerProtection(builder.Configuration.GetSection("Swagger"));  // belirli bir bölümden
services.AddSwaggerProtection(o =>                                            // kod içi
{
    o.Authority = "https://id.example.com";
    o.ProtectedPaths = new() { "swagger", "swagger/v1/swagger.json" };
    o.AllowedRoles   = new() { "admin" };
});

4.c) NuGet ile Dağıtım

İki paket üretilir:

Paket Ne zaman kullanılır Bağımlılıkları
NextQuantumSystem.Protect.SwaggerGuard Düz ASP.NET Core host Microsoft.IdentityModel.*
NextQuantumSystem.Protect.SwaggerGuard.Abp ABP host ↑ çekirdek + Volo.Abp.AspNetCore

ABP paketini kurduğunuzda çekirdek paket otomatik gelir (bağımlılık olarak tanımlı). ABP host'ta sadece .Abp paketini kurmanız yeterli.

Paketleri üret (./artifacts altına iki .nupkg):

dotnet pack NextQuantumSystem.Protect.slnx -c Release -o ./artifacts

Genel nuget.org'a gönder:

dotnet nuget push "artifacts/*.nupkg" --source https://api.nuget.org/v3/index.json --api-key <NUGET_API_KEY> --skip-duplicate

⚠️ nuget.org'a çıkan bir sürüm silinemez (yalnızca "unlist" edilebilir) ve paket ID'si global olarak rezerve olur.

Otomatik yayın (CI/CD — önerilen)

.github/workflows/build.yml ile:

  • Her push/PR → derle + test + paketle (artifact olarak yüklenir).
  • GitHub Release yayınlandığında → nuget.org'a otomatik push.

Yayın, NuGet Trusted Publishing (OIDC) ile yapılır — repoda uzun ömürlü API key secret'ı tutulmaz; production ortamı üzerinden kısa ömürlü key alınır.

Yeni sürüm yayınlama akışı:

# 1) csproj'larda <Version>'ı artır (ör. 1.0.2), commit + push
# 2) GitHub'da o sürüm için Release oluştur (tag: v1.0.2)
#    → build.yml otomatik pack + push eder

5. Konfigürasyon Referansı

appsettings.json içindeki "Swagger" bölümü SwaggerProtectionOptions'a bind edilir.

{
  "Swagger": {
    "IsEnabled": true,
    "RoutePrefix": "swagger",
    "DocumentTitle": "API Dokümanı",
    "CookieName": "__auth_token",
    "CookieExpirationHours": 8,
    "TokenInputPath": "auth/swagger",
    "ProtectedPaths": [ "swagger", "api/abp/api-definition", "swagger/v1/swagger.json" ],
    "AllowedRoles": [ "admin" ],
    "Authority": "https://id.example.com",
    "Audience": "my-service",
    "ValidateAudience": false,
    "ValidateIssuer": true,
    "RequireHttpsMetadata": true,
    "RoleClaimTypes": [ "role", "roles" ]
  }
}
Ayar Tip Varsayılan Açıklama
IsEnabled bool true false ise middleware hiçbir şey yapmaz (koruma kapalı).
RoutePrefix string "swagger" Bilgilendirme amaçlı; returnUrl fallback'i olarak kullanılır.
DocumentTitle string "API Dokümanı" Token giriş sayfasının <title>'ı.
CookieName string "__auth_token" Doğrulanmış JWT'nin saklandığı cookie.
CookieExpirationHours int 8 Cookie geçerlilik süresi (saat).
TokenInputPath string "auth/swagger" Token giriş sayfasının yolu. Asla ProtectedPaths içinde olmamalı (sonsuz redirect).
ProtectedPaths string[] [] Korunacak yol önekleri (leading slash'siz).
AllowedRoles string[] [] İzin verilen roller. Boşsa: doğrulanmış herhangi bir token yeterli sayılır.
Authority string? null Token'ı üreten OpenID/OAuth otoritesi; JWKS buradan çekilir. Doğrulama için zorunlu.
Audience string? null Beklenen audience (ValidateAudience=true ise zorunlu).
ValidateAudience bool false Audience doğrulaması yapılsın mı?
ValidateIssuer bool true Issuer doğrulaması (Authority'den gelen issuer ile).
RequireHttpsMetadata bool true Authority metadata için HTTPS zorunlu mu? (dev'de false).
RoleClaimTypes string[] ["role","roles",".../role"] Rol claim'lerinin okunacağı tip listesi (IdP'ler farklıdır).

📄 Tam örnek + açıklamalı senaryolar: samples/appsettings.Swagger.sample.jsonc — her ayarın satır-içi açıklaması ve 5 hazır senaryo (production, development, rol-kısıtsız, audience-doğrulamalı, kapalı).

Her projede değişen değerler (Authority, Audience) DLL içinde değil, her host'un kendi config'inde tutulur. Tekrarı azaltmak için: ortak appsettings.shared.json, environment variable (Swagger__Authority=...) veya kod-içi AddSwaggerProtection(o => ...) overload'u kullanılabilir.


6. Güvenlik Notları

  • 🔴 JWT imzası MUTLAKA doğrulanır. Authority yapılandırılmazsa doğrulama başarısız döner — token asla "sadece decode edilip" kabul edilmez. İmza + issuer + expiry hep doğrulanır. Bu, saldırganın kendi role=admin token'ını üretmesini engeller.
  • 🔁 Sonsuz redirect koruması: TokenInputPath asla korunan değildir; kendi içinde ele alınır.
  • 🍪 Cookie: HttpOnly (JS erişemez) + Secure (HTTPS'te) + SameSite=Lax. Bayat/geçersiz cookie otomatik silinir.
  • ↩️ Open-redirect koruması: returnUrl yalnızca site-içi (yerel) yollara izin verir; // veya mutlak URL'ler reddedilir.
  • ⚠️ api/abp/api-definition'ı korumak, ABP dinamik client-proxy üretimini etkileyebilir (cookie'siz çağıran araçlar 302 alır). Bilinçli tercih olmalı.
  • 🌐 Gateway/reverse-proxy: X-Forwarded-* / PathBase algılanan yolu değiştirebilir; ProtectedPaths eşleştirmesi buna göre ayarlanmalı.

7. Test

In-memory TestServer üzerinde gerçek HTTP akışıyla 10 integration testi. JWKS yerine simetrik anahtarlı bir doğrulayıcı enjekte edilerek tüm middleware mantığı sınanır.

dotnet test NextQuantumSystem.Protect.slnx
Senaryo Beklenen
Serbest yol (/healthz) 200 (geçer)
Korunan yol, cookie yok 302 → /auth/swagger?returnUrl=...
Giriş sayfası GET 200 + HTML
POST geçerli admin token 302 + Set-Cookie
POST geçerli non-admin token 403
POST geçersiz token 401
POST expired token 401
Korunan yol + geçerli admin cookie 200 (geçer)
Korunan yol + non-admin cookie 403
Korunan yol + bozuk cookie 302 + cookie silinir

Sonuç: 10/10 geçiyor.


8. Sık Sorulanlar

S: Bu bir ABP modülü mü, yoksa düz kütüphane mi? İkisi de. Çekirdek (SwaggerGuard) ABP'siz düz kütüphanedir; SwaggerGuard.Abp onu ABP host'ları için otomatik wire eden ince bir modüldür.

S: Her mikroservis için ayrı DLL derlemek gerekir mi? Hayır. Aynı DLL tüm projelerde kullanılır; sadece appsettings.json değişir.

S: NuGet çoklu dilli README destekler mi? NuGet pakette tek README gösterir. Burada kullanılan yöntem: tek README içinde dil bölümleri + en üstte dil seçici.


9. Sürüm Geçmişi

1.0.2 — 2026-07-18

  • Çoklu hedefleme: net8.0, net9.0, net10.0 desteği. Artık daha çok proje paketi kurabilir.
  • ABP paketi her framework için uygun ABP major'ını referanslar (net8.0→8.3.4, net9.0→9.3.7, net10.0→10.5.0).
  • Testler üç framework'te de çalışır — her birinde 10/10 geçiyor.
  • Not: net6.0/net7.0 bilinçli olarak hedeflenmedi (destek dışı & ABP kaldırdı); taban net8.0 (LTS).

1.0.1 — 2026-07-18

  • Çok dilli README (English + Türkçe), en üstte dil seçici.

1.0.0 — 2026-07-18

  • İlk sürüm.
  • SwaggerProtectionMiddleware: path eşleştirme, cookie tabanlı JWT geçidi, rol kontrolü, redirect akışı.
  • JwksJwtTokenValidator: Authority/JWKS ile imza + issuer + expiry doğrulaması.
  • Token giriş sayfası (MVC'siz, HTML render).
  • Düz ASP.NET Core için AddSwaggerProtection / UseSwaggerProtection extension'ları.
  • ABP host'ları için ProtectSwaggerGuardModule (tek [DependsOn] ile otomatik wiring).
  • 10 integration testi (in-memory TestServer).
  • NuGet paketleme: SwaggerGuard (düz) ve SwaggerGuard.Abp (ABP) paketleri.
  • Açıklamalı örnek config: samples/appsettings.Swagger.sample.jsonc.
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on NextQuantumSystem.Protect.SwaggerGuard:

Package Downloads
NextQuantumSystem.Protect.SwaggerGuard.Abp

SwaggerGuard korumasını ABP host'larına tek [DependsOn] ile otomatik ekleyen ABP modülü. NextQuantumSystem.Protect.SwaggerGuard çekirdeğini sarar.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.5.1 207 7/20/2026
1.0.2 135 7/18/2026
1.0.1 130 7/18/2026
1.0.0 131 7/18/2026