COMPUTER ENGINEER

Jump to examples
Blog
Next.js / ASP.NET Core / SQL6 min study
24/ 41

Identity and security

Authorization: roles, policies and ownership

The difference between 401 and 403, and the most skipped check: is this resource really yours?

UnderstandStudy an examplePractise

Understand the concept

Authentication establishes who you are; authorization decides what you may do. When an unauthenticated request reaches a protected resource the response is 401 (prove who you are first). An authenticated user without permission gets 403 (we know you, but no). ASP.NET Core does this automatically: an anonymous user gets a challenge, an unauthorised one a forbid.

Role-based authorization ([Authorize(Roles = "Admin")]) suffices for simple cases. For more flexible rules, policies are used: a policy can evaluate claims, the resource itself or custom logic. Policies are defined once in Program.cs and attached to endpoints by name.

The most common mistake is skipping object-level authorization (BOLA / IDOR). For ‘/api/invoices/42’ it is not enough that the user is signed in; invoice 42 must belong to that user. Otherwise a user reaches other people’s data just by changing the number in the URL. The check is done by adding an ownership condition to the query itself.

WHEN TO USE IT

Missing object-level authorization is the most common API vulnerability.

COMMON PITFALL

Adding [Authorize] alone without checking who owns the resource.

LIVE ANIMATION

A letter’s journey through the city

Think of a request as a letter and the server as a city. Pick a scenario, press play and watch which gates the letter passes and where it gets stopped.

CLIENTEDGEWEB SERVERAPI · ASP.NET COREDATABrowserThe user’s screenNetworkDNS · TCP · TLSReverse proxyTLS termination, compressionNext.js serverSSR and route handlersKestrelHTTP serverException handlerMiddlewareRoutingEndpoint selectionRate limiterMiddlewareAuthenticationWho you areAuthorizationWhat you may doModel bindingHTTP → C# + validationControllerEndpoint codeServiceBusiness rules (DI)RedisDistributed cacheEF CoreLINQ → SQLSQL ServerQuery plan, indexes
OUTBOUND →

Someone asks for admin messages without signing in.

BrowserYour screen. It writes the request and finally turns the answer into a page.
1 / 6
01 / PRACTICE

One topic. Three levels of depth.

Illustrative example
[Authorize(Roles = "Admin")]
[HttpDelete("{id:int}")]
public Task<IActionResult> Delete(int id, CancellationToken ct) => …

Only users in the Admin role can delete.

This page connects to no real server or database. Code samples are illustrative for .NET 8, Next.js and SQL Server; timings are example values in the simulation, not measurements. Try samples only in your own development environment; never share real connection strings, tokens or passwords.

02 / YOUR TURN

Try it yourself first.

User A sees their order at /api/orders/1001. Typing 1002 opens user B’s order. The endpoint is protected with [Authorize]. What is the problem and the fix?

Show the solution and explanation
Worked solution
Sorun: nesne düzeyinde yetkilendirme yok (BOLA/IDOR).
Düzeltme: sorguya OwnerId == currentUserId koşulu ekle,
eşleşmezse 404 dön. Kimliği istemciden değil token’dan/oturumdan al.

[Authorize] only answers ‘is the user signed in’; the code must ask ‘is this record theirs’.