JWT Structure and Claims
Understand header, payload, and signature.
JWT Structure and Claims is a free C# Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is a JWT?
A JSON Web Token (JWT) is a compact, URL-safe token format used to securely transmit claims between two parties. In ASP.NET Core it is the most common way to authenticate stateless APIs.
A JWT is just a string made of three Base64Url-encoded parts joined by dots: header.payload.signature.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0Iiwicm9sZSI6ImFkbWluIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cThe Header
The header describes how the token is signed. It is a small JSON object that gets Base64Url-encoded into the first segment.
alg names the signing algorithm (e.g. HS256, RS256) and typ is almost always JWT.
{
"alg": "HS256",
"typ": "JWT"
}The Payload
The payload carries the claims - statements about the user and metadata about the token. It is the second segment.
Important: the payload is only encoded, not encrypted. Anyone can decode it, so never put secrets here.
{
"sub": "1234",
"name": "Alice",
"role": "admin",
"exp": 1735689600
}The Signature
The signature guarantees the token has not been tampered with. The server computes it from the encoded header, the encoded payload and a secret key.
If anyone changes a single character of the payload, the signature no longer matches and validation fails.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secretKey
)Registered Claims
Some claim names are standardized by the JWT spec (RFC 7519). They use short three-letter keys:
iss- issuersub- subject (the user id)aud- audienceexp- expiration time (Unix seconds)nbf- not valid beforeiat- issued at
{
"iss": "https://api.myapp.com",
"aud": "myapp-clients",
"sub": "42",
"exp": 1735689600,
"iat": 1735686000
}Custom Claims
Beyond the registered set, you can add any custom claims your application needs - roles, permissions, tenant ids, email and more.
Keep the payload small: every claim travels on every request.
{
"sub": "42",
"email": "alice@myapp.com",
"role": "admin",
"tenant_id": "acme",
"permissions": ["orders:read", "orders:write"]
}Claims in ASP.NET Core
In .NET, claims are modeled by the System.Security.Claims.Claim type. Each claim is a type / value pair.
When a JWT is validated, ASP.NET Core turns each payload entry into a Claim on the user's ClaimsPrincipal.
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, "42"),
new Claim(ClaimTypes.Name, "Alice"),
new Claim(ClaimTypes.Role, "admin"),
new Claim("tenant_id", "acme")
};ClaimsPrincipal and ClaimsIdentity
An authenticated user is represented by a ClaimsPrincipal, which wraps one or more ClaimsIdentity objects, each holding a set of claims.
In a controller you reach it through User.
// Inside a controller action
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
bool isAdmin = User.IsInRole("admin");
string? tenant = User.FindFirst("tenant_id")?.Value;Claim Type Mapping
By default the JWT handler maps short JWT keys to long URI-style claim types (for example sub becomes ClaimTypes.NameIdentifier).
To keep the original short names, disable the inbound mapping once at startup.
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
// Now User.FindFirst("sub") returns the raw 'sub' claimWhy Not Just a Session Cookie?
JWTs are self-contained: the server can validate them using only the signing key, with no database lookup or server-side session store.
This makes them ideal for horizontally scaled APIs and microservices where any node can verify the same token.
// Client sends the token on every request:
// Authorization: Bearer eyJhbGciOiJIUzI1Ni...The Trade-off: Revocation
Because a JWT is self-contained and trusted until it expires, you cannot easily revoke one before its exp time.
The common mitigation is to keep access tokens short-lived and pair them with refresh tokens (covered later in this course).
// Short-lived access token
exp = iat + 15 * 60; // 15 minutesQuick Check
Test your understanding of JWT structure.
Recap
You learned the anatomy of a JWT and how claims work in ASP.NET Core:
- A JWT is
header.payload.signature, each Base64Url-encoded. - The payload holds registered and custom claims, encoded but not encrypted.
- The signature guarantees integrity using a secret or key pair.
- .NET turns claims into a
ClaimsPrincipalyou read viaUser.
Next, you will configure ASP.NET Core to validate these tokens.
Frequently asked questions
Is the “JWT Structure and Claims” lesson free?
Yes — the full text of “JWT Structure and Claims” is free to read here on the web, and the C# Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.
What will I learn in “JWT Structure and Claims”?
Understand header, payload, and signature. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C# Academy?
No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “JWT Structure and Claims” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C# Academy lesson?
Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- JWT Structure and Claims
- Configuring JWT Bearer Authentication
- Issuing Tokens
- Refresh Tokens and Expiry