Authorization middleware doesn’t “guess” permissions—it evaluates policies against the authenticated user’s claims.
How it actually checks permissions, step by step
When a request reaches authorization:
- It looks at attributes like:
[Authorize]
[Authorize(Roles = "Admin")]
[Authorize(Policy = "CanEditProducts")]
This metadata is attached during routing.
From earlier middleware:
app.UseAuthentication();
-
HttpContext.Useris already populated -
Contains:
- Claims (name, role, email, etc.)
- Authentication status
If user is not authenticated → immediately returns 401
Each [Authorize] turns into a policy containing requirements:
Examples:
-
[Authorize]→ must be authenticated -
[Authorize(Roles = "Admin")]→ must have role = Admin (To be passed need Admin Role) -
[Authorize(Policy = "CanEditProducts")]→ custom rules (To be passed need Edit permission)
Core component:
-
IAuthorizationService
It checks each requirement:
await authorizationService.AuthorizeAsync(user, resource, policy);
Each policy has:
- Requirements (rules)
- Handlers (logic to validate rules)
[Authorize(Roles = "Admin")]
Internally checks:
user.IsInRole("Admin")
services.AddAuthorization(options =>
{
options.AddPolicy("CanEditProducts", policy =>
policy.RequireClaim("permission", "edit"));
});
Checks:
user.HasClaim("permission", "edit")
Success
- All requirements pass → request continues to controller
Failure cases:
- Not authenticated → 401 Unauthorized
- Authenticated but fails policy → 403 Forbidden
Request → Authentication → Authorization → Controller
↓
HttpContext.User
↓
Check Policy/Claims
↓
Allow or Block Request
Authorization is basically:
“Does this user’s claims satisfy the policy requirements?”
Request:
GET /admin/dashboard
Controller:
[Authorize(Roles = "Admin")]
User claims:
{
"name": "John",
"role": "User"
}
Result:
- Authenticated → Pass
- Not in Admin role
→ 403 Forbidden
Authorization middleware checks permissions by:
Comparing user claims against policy requirements using handlers