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:

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.

Understanding Claims in ASP.NET Core JWT Authentication

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:

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/orders

The API needs to know:

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:

ClaimPurpose
subUser ID
nameUser Name
emailEmail Address
roleUser Role
expExpiration Time

For our SecureShop API, we'll include:

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.User

Your 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    : Customer

John requests:

GET /api/profile
 Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

ASP.NET Core validates the token.

Then it creates:

HttpContext.User

Now the controller can read:

User Id  → 101
 Name     → John
 Email    → [email protected]
 Role     → Customer

No 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 Claims

This 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:

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:

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:

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

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.