[Authorize] va [AllowAnonymous] — route himoya qilish
Muammodan boshlaylik
JwtBearer sozlandi (60-dars), token ishlaydi. Lekin GET /api/buyurtmalar ga tokensiz so'rov yuborilsa — hammasi qaytadi. Middleware tokenni tekshiradi va User ni to'ldiradi, ammo hech kim "bu endpoint ga faqat kirgan foydalanuvchi" deb aytmagan.
Autentifikatsiya (kim?) va avtorizatsiya (ruxsat bormi?) — ikki alohida bosqich.
| Autentifikatsiya | Avtorizatsiya | |
|---|---|---|
| Savol | Siz kimsiz? | Sizga bu mumkinmi? |
| Xato | 401 Unauthorized |
403 Forbidden |
| Misol | Token yaroqli | Admin emas — o'chira olmaydi |
Hayotiy o'xshatma
Mehmonxona. Qabulxonada pasport ko'rsatasiz — kim ekaningiz aniqlandi (autentifikatsiya). Kartangiz faqat 305-xona va zalni ochadi — boshqa xonalar yopiq (avtorizatsiya). Restoran va qabulxona esa hamma uchun ochiq (AllowAnonymous).
[Authorize] — faqat kirganlar
[ApiController]
[Route("api/buyurtmalar")]
[Authorize] // butun controller
public class BuyurtmalarController(DokonDbContext db) : ControllerBase
{
[HttpGet]
public async Task<IActionResult> Meniki(CancellationToken ct)
{
var id = User.FoydalanuvchiId();
return Ok(await db.Buyurtmalar.Where(b => b.MijozId == id).ToListAsync(ct));
}
}
- Token yo'q / yaroqsiz / muddati o'tgan — 401, action ishga tushmaydi
- Token yaroqli — action bajariladi,
Userto'ldirilgan
[AllowAnonymous] — istisno
[ApiController]
[Route("api/mahsulotlar")]
[Authorize]
public class MahsulotlarController : ControllerBase
{
[HttpGet]
[AllowAnonymous] // katalogni hamma ko'radi
public IActionResult Royxat() => Ok(...);
[HttpPost] // qo'shish — faqat kirganlar
public IActionResult Yarat(MahsulotYaratDto dto) => ...;
}
[AllowAnonymous] har qanday [Authorize] ni (controller va global darajadagini ham) bekor qiladi.
Global himoya — "sukut bo'yicha yopiq"
Har bir controller ga [Authorize] yozishni unutish oson. Teskarisi xavfsizroq — hammasini yopib, ochiqlarini aniq belgilash:
builder.Services.AddAuthorization(o =>
{
o.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
Endi atributsiz har bir endpoint ham autentifikatsiya talab qiladi; login, ro'yxatdan o'tish, health check — [AllowAnonymous].
[HttpPost("login")]
[AllowAnonymous]
public async Task<ActionResult<TokenJavob>> Login(LoginDto dto, CancellationToken ct) { ... }
[!TIP] "Sukut bo'yicha yopiq" (secure by default) — yangi endpoint qo'shilsa va himoya unutilsa ham, u ochiq qolib ketmaydi. Eng yomon holatda — kimdir 401 olib,
[AllowAnonymous]qo'shish kerakligini sezadi; bu sizib chiqqan ma'lumotdan ko'ra ancha yaxshi.
Policy — nomlangan qoidalar
builder.Services.AddAuthorization(o =>
{
o.AddPolicy("EmailTasdiqlangan", p => p.RequireClaim("email_verified", "true"));
o.AddPolicy("Admin", p => p.RequireRole("admin"));
o.AddPolicy("Kattalar", p => p.RequireAssertion(ctx =>
int.TryParse(ctx.User.FindFirstValue("yosh"), out var y) && y >= 18));
});
[Authorize(Policy = "EmailTasdiqlangan")]
[HttpPost("buyurtma")]
public IActionResult Buyurtma(...) => ...;
Bir nechta [Authorize] atributi — barchasi bajarilishi kerak (AND).
Resurs egasini tekshirish
[Authorize] "kirganmi?" deb so'raydi, lekin "bu buyurtma unikimi?" deb so'ramaydi:
[HttpGet("{id:int}")]
public async Task<IActionResult> Ol(int id, CancellationToken ct)
{
var b = await db.Buyurtmalar.FindAsync([id], ct);
if (b is null) return NotFound();
if (b.MijozId != User.FoydalanuvchiId() && !User.IsInRole("admin"))
return NotFound(); // yoki Forbid() — mavjudligini ham oshkor qilmaslik uchun 404
return Ok(b);
}
[!WARNING] IDOR (Insecure Direct Object Reference) — eng keng tarqalgan API zaifliklaridan biri:
/api/buyurtmalar/1001ni/1002ga o'zgartirib, boshqaning ma'lumotini ko'rish. Har bir ID bo'yicha so'rovda egalikni tekshiring — yoki so'rovning o'zida filtrlang:Where(b => b.Id == id && b.MijozId == meningId).
Minimal API da
app.MapGet("/api/profil", (ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Email))
.RequireAuthorization();
app.MapGet("/api/admin/statistika", () => ...)
.RequireAuthorization("Admin");
app.MapGet("/api/salom", () => "Salom").AllowAnonymous();
Tez-tez uchraydigan xatolar
UseAuthorization yo'q — [Authorize] bor endpoint lar ishlashdan to'xtaydi (xato bilan); middleware kerak.
401 va 403 ni aralashtirish — tokensiz → 401; token bor, huquq yo'q → 403.
Faqat [Authorize] ga ishonish — resurs egaligi alohida tekshiriladi (IDOR).
Xulosa
Autentifikatsiya — kim (401), avtorizatsiya — ruxsat (403). [Authorize] — controller yoki action ni faqat kirganlarga; [AllowAnonymous] — istisno. FallbackPolicy + RequireAuthenticatedUser — hammasi sukut bo'yicha yopiq, ochiqlari aniq belgilanadi.
Policy — nomlangan qoidalar (RequireClaim, RequireRole, RequireAssertion), [Authorize(Policy = "...")]. Resurs egaligi — har bir ID so'rovida alohida tekshiriladi (IDOR). Minimal API: RequireAuthorization(), AllowAnonymous().
Keyingi dars
62-dars: Refresh Token — uzoq muddatli sessiya, rotatsiya