In the previous article, we protected our API endpoints using the [Authorize] attribute. Once a request contains a valid JWT, ASP.NET Core allows the user to access protected resources.
But another important question arises:
The API know who the logged-in user is?
For example:
Which customer placed this order?
Which user is viewing their profile?
Which administrator is updating a product?
The answer is Claims.
When ASP.NET Core validates a JWT, it reads the information stored inside the token and makes it available through HttpContext.User.
In this article, you'll learn what claims are, how ASP.NET Core creates them, and how to access the logged-in user's information inside your Web API.

What Are Claims?
A Claim is a piece of information about an authenticated user.
Think of a company employee ID card.
The card contains information such as:
Employee ID
Name
Department
Designation
The security guard doesn't need to ask for these details every time because they're already printed on the card.
A JWT works in a similar way.
Instead of storing this information on an ID card, it stores it inside the token as Claims.
Why Do We Need Claims?
Imagine our SecureShop API.
A customer logs in successfully.
Now the customer requests:
GET /api/ordersThe API needs to know:
Which customer owns these orders?
Is the customer authenticated?
What role does the customer have?
Without claims, the API would need to query the database just to identify the user on every request.
Claims solve this problem by carrying essential identity information inside the JWT.
Common Claims in JWT
A JWT can contain many claims.
Some commonly used claims are:
| Claim | Purpose |
|---|---|
| sub | User ID |
| name | User Name |
| Email Address | |
| role | User Role |
| exp | Expiration Time |
For our SecureShop API, we'll include:
User ID
Name
Email
Role
This information is enough to identify the current user.
Creating Claims While Generating the JWT
In Article 4, we created the JWT using JwtTokenService.
The claims looked like this:
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.Name),
new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.Role, user.Role)
};Each Claim becomes part of the JWT payload.
After the token is generated, these values travel with every authenticated request.
How ASP.NET Core Uses Claims
When a request reaches the API, ASP.NET Core validates the JWT.
If validation succeeds, it reads all claims from the token and creates an authenticated user.
Internally, the process looks like this:
JWT
│
▼
Read Claims
│
▼
ClaimsIdentity
│
▼
ClaimsPrincipal
│
▼
HttpContext.UserYour controller never reads the JWT directly.
Instead, it works with the authenticated user created by ASP.NET Core.
Accessing Claims Inside a Controller
Every controller inherits from ControllerBase.
This provides access to the current authenticated user through the User property.
For example:
[Authorize]
[HttpGet("profile")]
public IActionResult GetProfile()
{
var userName = User.Identity?.Name;
return Ok(userName);
}If the JWT contains a name claim, the API returns the logged-in user's name.
Reading Individual Claims
Sometimes you need specific information, such as the user's email or ID.
You can retrieve them like this:
var userId = User.FindFirst(JwtRegisteredClaimNames.Sub)?.Value;
var email = User.FindFirst(ClaimTypes.Email)?.Value;
var role = User.FindFirst(ClaimTypes.Role)?.Value;Each call searches the authenticated user's claims and returns the matching value.
Practical Example
Let's continue with our SecureShop API.
Suppose John logs in.
The generated JWT contains these claims:
User Id : 101
Name : John
Email : [email protected]
Role : CustomerJohn requests:
GET /api/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...ASP.NET Core validates the token.
Then it creates:
HttpContext.UserNow the controller can read:
User Id → 101
Name → John
Email → [email protected]
Role → CustomerNo additional database query is required just to identify the current user.
Internal Flow
The complete flow looks like this:
Client
│
│ JWT
▼
Authentication Middleware
│
▼
Validate JWT
│
▼
Extract Claims
│
▼
Create ClaimsPrincipal
│
▼
HttpContext.User
│
▼
Controller Reads ClaimsThis happens automatically for every authenticated request.
When Should You Use Claims?
Claims are ideal for information that your application frequently needs during request processing.
Examples include:
Current User ID
Username
Email Address
Role
Tenant ID (for multi-tenant applications)
Keep claims small and relevant.
If the data changes frequently or is very large, retrieve it from the database instead of storing it in the JWT.
Common Mistakes
Mistake 1: Storing Too Much Data in Claims
Some developers place entire user profiles inside the JWT.
For example:
Address
Phone numbers
Preferences
Shopping cart
Large JSON objects
This increases the token size and sends unnecessary data with every request.
Store only information needed for authentication and authorization.
Mistake 2: Storing Sensitive Information
Never store:
Passwords
OTPs
Credit card numbers
API keys
Connection strings
Remember:
A JWT payload is encoded—not encrypted.
Mistake 3: Reading Claims Without Authentication
If the endpoint is not protected using[Authorize], the request may not have an authenticated user.
Always verify that authentication has occurred before depending on claim values.
Mistake 4: Querying the Database for User Identity Every Time
If the required information already exists in the JWT claims, use it.
Avoid unnecessary database queries for data such as User ID, Name, or Role.
Key Takeaways
Claims are pieces of information about the authenticated user.
Claims are stored inside the JWT payload when the token is generated.
After JWT validation, ASP.NET Core creates a
ClaimsPrincipaland exposes it throughHttpContext.User.Controllers can easily access values like User ID, Name, Email, and Role without reading the JWT manually.
Keep claims small, relevant, and free of sensitive information.
In the next article, we'll build on these claims by implementing Role-Based Authorization. You'll learn how to restrict endpoints so that only specific users—such as Admins, Customers, or Managers—can access certain parts of your ASP.NET Core Web API.

Join the conversation! Your thoughts help the community grow.