Day 24: Authorization (Role & Policy-Based)
Welcome to Day 24. Yesterday, we set up Authentication (verifying who you are). Today, we implement Authorization (verifying what you are allowed to do).
Just because Bob logging in successfully doesnât mean Bob should be able to delete the entire production database.
Claims & Roles
Inside a JWT, you can store data about the user safely (as long as itâs not sensitive, like passwords). These pieces of data are called Claims.
A very common claim is the role.
- Alice:
role: Admin - Bob:
role: User
When generating a token for Alice upon login in C#, you would inject the role claim into the JWT:
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.Id),
new Claim(ClaimTypes.Role, "Admin")
};
Role-Based Authorization
When the token comes back to the server, ASP.NET Core magically parses its claims. You can restrict endpoints immediately based on Roles!
Controllers
[Authorize(Roles = "Admin")]
[HttpDelete("{id}")]
public IActionResult DeleteUser(int id) { ... }
Minimal APIs
app.MapDelete("/users/{id}", (int id) => { ... })
.RequireAuthorization(new AuthorizeAttribute { Roles = "Admin" });
If Bob (who only has User) hits this endpoint, ASP.NET Core intercepts it and returns a 403 Forbidden. The method logic never executes!
Policy-Based Authorization
Roles are great, but they are rigid. What if you have a complex rule: âUsers can delete posts, but only if they are the original author of the post OR if they are an Admin.â
You canât do this easily with [Authorize(Roles="Admin,Author")]. Instead, ASP.NET Core provides Policies.
First, define the Policy in Program.cs:
builder.Services.AddAuthorization(options =>
{
// Define a rule: You must be at least 18 AND have an employee badge!
options.AddPolicy("MustBeAdultEmployee", policy =>
{
policy.RequireClaim("Age", "18", "19", "20", "21"); // Oversimplified!
policy.RequireClaim("EmployeeBadge");
});
});
Then, apply the Policy to the endpoint!
app.MapGet("/employee-lounge", () => "Welcome to the lounge.")
.RequireAuthorization("MustBeAdultEmployee");
Challenge for Day 24
In yesterdayâs JWT authentication setup, try modifying the app.MapGet requirement to use a custom policy. Define a policy in AddAuthorization(options => ...) that requires a specific claim like âDepartmentâ to equal âITâ. Mint a token with jwt.io containing that claim, and hit the endpoint!
Tomorrow: Configuration & Secrets Management (Hiding that JWT Key!).