Privacy has never been a choice. Parts of your identification, like your name, email address, and occasionally even your location or payment information, are shared each time you use a service, order food, or log into an app. However, when we click "Login," we typically don't give much thought to what goes on behind the scenes.

Authorization vs. Authentication: The Most Perplexing Ideas
This is still best illustrated by a straightforward real-world example: picture yourself entering a hotel.
They verify your reservation and verify your identity at the front desk. That is authentication, or demonstrating that you are who you say you are.
Now picture yourself attempting to enter a restricted location like the VIP lounge. You might not be permitted entry even if you are a visitor. Authorization is the process of determining what you are permitted to do.
Even now, a lot of systems fail due to poorly designed authorization rather than insufficient authentication.
How We Used to Do It (and Why It Changed)
A few years ago, most applications relied heavily on session-based authentication.
You logged in with a username and password. The server stored your session. Every request depended on that session being valid.
That worked well for simple applications, but it didn't scale well for:
- Mobile apps
- Microservices
- Distributed systems
- APIs
This is where token-based authentication became the standard.
Tokens: Your Digital Identity Card
Think of a token as a digital ID card.
Instead of asking the server "who are you?" on every request, you just present your token.
The server trusts the token and allows or denies access based on what's inside it.
What is a JWT?
A JWT (JSON Web Token) is a compact, secure way to transmit information between systems.
But here's an important correction from older explanations:
- A JWT is not inherently secure by itself
- It is signed (and sometimes encrypted) to ensure integrity
You can think of it as a sealed envelope:
- Anyone can read it (unless encrypted)
- But no one can tamper with it without breaking the seal
JWT Structure (Still the Same, Still Important)
A JWT has three parts:
Header
Contains metadata like the signing algorithm (e.g., HS256, RS256)
Payload
Contains claims (data about the user)
Common claims include:
- sub: user identifier
- iss: issuer (who created the token)
- aud: audience (who the token is for)
- exp: expiration time
Signature
Ensures the token hasn't been modified
One important clarification: The signing algorithm is defined in the Header, not the Signature
OAuth2 and OpenID Connect
OAuth2
OAuth2 is not an authentication protocol.
It is an authorization framework that allows one application to access resources from another on behalf of a user.
Example:
When you click "Login with Google", your app does NOT get your password.
Instead:
- Google authenticates you
- Google gives your app a token
- Your app uses that token to access limited user data
So OAuth2 is about: delegating access, not identifying the user
OpenID Connect (OIDC)
OpenID Connect sits on top of OAuth2 and adds authentication.
It introduces the concept of an ID Token, which is usually a JWT.
This ID token tells your application who the user is
So in modern systems:
- OAuth2 : authorization (access to resources)
- OIDC : authentication (identity)
- Common Mistakes (Still Happening Today)
Even in modern systems, developers still fall into these traps:
1. Putting sensitive data in JWT payload
JWTs are not encrypted by default. Never store passwords or secrets.
2. Not validating tokens properly
Always validate:
- Signature
- Expiration
- Issuer
- Audience
3. Long-lived tokens
Short-lived access tokens + refresh tokens are the safer approach.
ASP.NET Core Identity
ASP.NET Core Identity is the default membership system provided by Microsoft. It handles everything related to user management.
- User registration and login
- Password hashing (secure by default)
- Roles and claims
- Token generation
For APIs and modern apps, JWT authentication is the standard.
Instead of sessions, you issue a token after login.
Basic JWT Setup
builder.Services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "test-app",
ValidAudience = "test-app",
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes("your-secret-key"))
};
});
Authorization (Roles, Claims, Policies)
As mentioned before, authentication tells you who the user is, but authorization defines what they can do.
Role-based authorization
[Authorize(Roles = "Admin")]
public IActionResult AdminOnly()
{
return Ok("Admin access");
}
Claims-based authorization
[Authorize(Policy = "CanEdit")]
public IActionResult Edit()
{
return Ok();
}
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CanEdit", policy =>
policy.RequireClaim("permission", "edit"));
});
In modern systems, claims-based or policy-based authorization is preferred over simple roles because it’s more flexible. ASP.NET Core Identity is an interesting topic that i will share about more videos and tutorials for better understanding how it works in the future.