NextQuantumSystem.Protect.SwaggerGuard
1.0.2
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
<PackageReference Include="NextQuantumSystem.Protect.SwaggerGuard" Version="1.0.2" />
<PackageVersion Include="NextQuantumSystem.Protect.SwaggerGuard" Version="1.0.2" />
<PackageReference Include="NextQuantumSystem.Protect.SwaggerGuard" />
paket add NextQuantumSystem.Protect.SwaggerGuard --version 1.0.2
#r "nuget: NextQuantumSystem.Protect.SwaggerGuard, 1.0.2"
#:package NextQuantumSystem.Protect.SwaggerGuard@1.0.2
#addin nuget:?package=NextQuantumSystem.Protect.SwaggerGuard&version=1.0.2
#tool nuget:?package=NextQuantumSystem.Protect.SwaggerGuard&version=1.0.2
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 extraUse...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
.Abppackage.
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.
Automated publishing (CI/CD — recommended)
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 sharedappsettings.shared.json, environment variables (Swagger__Authority=...), or the in-codeAddSwaggerProtection(o => ...)overload.
6. Security Notes
- 🔴 The JWT signature is always verified. If
Authorityis 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 ownrole=admintoken. - 🔁 Infinite-redirect guard:
TokenInputPathis 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:
returnUrlallows only local (same-site) paths;//or absolute URLs are rejected. - ⚠️ Protecting
api/abp/api-definitionmay 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; tuneProtectedPathsaccordingly.
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.0are intentionally not targeted (out of support & dropped by ABP); the floor isnet8.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/UseSwaggerProtectionextensions for plain ASP.NET Core.ProtectSwaggerGuardModulefor ABP hosts (automatic wiring via a single[DependsOn]).- 10 integration tests (in-memory TestServer).
- NuGet packaging:
SwaggerGuard(plain) andSwaggerGuard.Abp(ABP) viadotnet 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 birUse...ç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
.Abppaketini 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: ortakappsettings.shared.json, environment variable (Swagger__Authority=...) veya kod-içiAddSwaggerProtection(o => ...)overload'u kullanılabilir.
6. Güvenlik Notları
- 🔴 JWT imzası MUTLAKA doğrulanır.
Authorityyapı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 kendirole=admintoken'ını üretmesini engeller. - 🔁 Sonsuz redirect koruması:
TokenInputPathasla 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ı:
returnUrlyalnı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;ProtectedPathseş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.0desteğ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.0bilinçli olarak hedeflenmedi (destek dışı & ABP kaldırdı); tabannet8.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/UseSwaggerProtectionextension'ları. - ABP host'ları için
ProtectSwaggerGuardModule(tek[DependsOn]ile otomatik wiring). - 10 integration testi (in-memory TestServer).
- NuGet paketleme:
SwaggerGuard(düz) veSwaggerGuard.Abp(ABP) paketleri. - Açıklamalı örnek config:
samples/appsettings.Swagger.sample.jsonc.
| Product | Versions 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. |
-
net10.0
- Microsoft.IdentityModel.JsonWebTokens (>= 8.16.0)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.16.0)
-
net8.0
- Microsoft.IdentityModel.JsonWebTokens (>= 8.16.0)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.16.0)
-
net9.0
- Microsoft.IdentityModel.JsonWebTokens (>= 8.16.0)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.16.0)
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.