🧩 در پشت صحنه چه اتفاقی میافتد؟
این کلاس در واقع هر دو نقش Requirement و Handler را با هم ترکیب کرده است —
یعنی هم مشخص میکند چه مجوزهایی لازماند، و هم چگونه باید بررسی شوند.
این کار باعث میشود منطق مرتبط در یک جا نگهداری شود و از تکرار (Boilerplate) جلوگیری کند.
هندلر در میان Claims کاربر جستوجو میکند تا Claimی با نوع Permission پیدا کند
که مقدار آن با یکی از مجوزهای موردنیاز مطابقت داشته باشد.
این عمل به صورت OR است — یعنی اگر کاربر حتی یکی از مجوزهای خواستهشده را داشته باشد، اجازهی دسترسی خواهد داشت ✅
اگر Claim موردنظر یافت شود، با فراخوانی
context.Succeed(requirement)
به ASP.NET Core اطلاع میدهیم که شرط تأیید شده است، و دیگر نیازی به بررسی بقیه نیست.
در صورت نیاز، میتوانید این رفتار را به AND تغییر دهید تا تمام مجوزها الزامی باشند 🔒
🏷 تعریف Claim Type سفارشی
برای شناسایی نوع مجوز در Claims، ابتدا باید نوع Claim خود را تعریف کنید:
public static class CustomClaimTypes
{
public const string Permission = "permission";
}
🪪 افزودن Claims هنگام صدور JWT Token
هنگام ساخت توکن JWT یا تنظیم Claims کاربر، میتوانید مجوزها را از دیتابیس خوانده و در Claims اضافه کنید:
var permissions = await (
from role in dbContext.Roles
join permission in dbContext.RolePermissions on role.Id equals permission.RoleId
where roles.Contains(role.Name)
select permission.Name)
.Distinct()
.ToArrayAsync();
List<Claim> claims =
[
new(JwtRegisteredClaimNames.Sub, user.Id),
new(JwtRegisteredClaimNames.Email, user.Email!),
..roles.Select(r => new Claim(ClaimTypes.Role, r)),
..permissions.Select(p => new Claim(CustomClaimTypes.Permission, p))
];
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddMinutes(configuration.GetValue<int>("Jwt:ExpirationInMinutes")),
SigningCredentials = credentials,
Issuer = configuration["Jwt:Issuer"],
Audience = configuration["Jwt:Audience"]
};
var tokenHandler = new JsonWebTokenHandler();
string accessToken = tokenHandler.CreateToken(tokenDescriptor);





