Privacy has never been optional. Every time you sign into an app, order food, or use a service, you are sharing pieces of your identity, your email, your name, sometimes even your location or payment details.
And yet, most of the time, we don't really think about what happens behind the scenes when we click "Login".
Authentication vs Authorization (Still the Most Confused Concepts)
A simple real-life example still explains this best: imagine you walk into a hotel.
At the reception, they check your identity and confirm your reservation. That's authentication (proving that you are who you claim to be).
Now, imagine you try to access the VIP lounge or a restricted area. Even if you are a guest, you might not be allowed in. That's authorization (deciding what you are allowed to do).
Even today, many systems fail not because authentication is weak, but because authorization is poorly designed.
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:
You can think of it as a sealed envelope:
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:
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:
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:
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.
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.