← Back to list

How I Secured My ASP.NET Core APIs Using JWT and [Authorize] (Real-World Guide)

When building modern applications, security is something you cannot ignore.

Chandjogani · 2026-07-07 11:06 · 0 claps · 3.4 min read
#aspnetcore #jwt-token #webapi #authentication #cybersecurity
Open on Medium ↗
Wiki topics: LIT · Literature & Writing 🔒 · Cybersecurity

How I Secured My ASP.NET Core APIs Using JWT and [Authorize] (Real-World Guide)

When building modern applications, security is something you cannot ignore.

Recently, I worked on an ASP.NET Core Web API consumed by a frontend application. Functionally, everything worked perfectly — but there was one major concern:

Anyone who knew the API URL could potentially access endpoints through Postman, Swagger, or any HTTP client.

That’s when I decided to implement JWT (JSON Web Token) authentication along with ASP.NET Core’s **[Authorize] attribute. Later, I also integrated the solution with Kong API Gateway** to add another layer of security.

In this article, I’ll share:

  • Why I chose JWT authentication
  • When JWT is the right choice
  • How [Authorize] protects APIs
  • A real mistake I made with Kong Gateway (and what I learned from it)

The Problem

My application’s architecture looked like this:

  • React/Angular frontend
  • ASP.NET Core Web API backend
  • Publicly exposed API endpoints
  • No authentication or authorization

This created several security risks:

  • Sensitive data could be accessed by unauthorized users
  • No identity verification
  • No access control
  • Increased attack surface

Although the application worked, it wasn’t secure.

The Solution: JWT Authentication

I needed an authentication mechanism that was:

  • Easy to implement
  • Scalable
  • Stateless
  • Suitable for modern web and mobile applications

JWT (JSON Web Token) turned out to be the perfect fit.

How JWT Works (In Simple Terms)

The authentication flow is straightforward:

  1. User logs in.
  2. Server verifies the user’s credentials.
  3. Server generates a JWT token.
  4. Client stores the token.
  5. Client sends the token with every request.
  6. Server validates the token before processing the request.

Once validated, the API knows exactly who the user is and whether they should be granted access.

Implementing JWT in ASP.NET Core

Example code to Configure JWT in Program.cs

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = builder.Configuration["JwtSettings:Issuer"],
        ValidAudience = builder.Configuration["JwtSettings:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(builder.Configuration["JwtSettings:Key"])),

        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true
    };
});

Note: Always enable ValidateLifetime in production to prevent expired tokens from being accepted.

Don’t forget to add before mapping controllers.:


app.UseAuthentication();
app.UseAuthorization();

Real Scenario: Employee Portal System

Imagine you’re developing an Employee Portal where users can:

  • View their profile
  • Access salary information
  • Download reports
  • Submit requests

Only authenticated employees should be able to access this data.

Your JWT settings might look like this:

"JwtSettings": {
  "Issuer": "https://auth.mycompany.com",
  "Audience": "employee-api",
  "Key": "MySuperSecretKey123"
}

Understanding Key Concepts

1. Issuer → Who Created the Token?

"Issuer": "https://auth.mycompany.com"

The issuer identifies the authority that generated the token.

In this case:

  • Employees authenticate through auth.mycompany.com
  • That server issues JWT tokens
  • APIs trust tokens generated by this issuer

Real-world analogy:

Think of it like: Passport issuing authority “Government of India issued this passport”. Similarly, your API trusts tokens issued by your authentication server.

What happens during validation?

ValidateIssuer = true

API checks: “Did this token come from auth.mycompany.com?”

Yes → allow No → reject

2. Audience → Who Should Use the Token?

"Audience": "employee-api" //Sometimes its a client id of an app

Many organizations have multiple applications and APIs:

  • employee-api
  • payroll-api
  • admin-api

This token is only for: employee-api

Real-life analogy:

You get an ID card for a specific building:

Office Building A → accept Office Building B → reject

You cannot use the same card everywhere

ValidateAudience = true

API checks: “Is this token meant for me?”

Yes → allow No → reject

3. Signing Key — How Do We Know the Token Wasn’t Modified?

"Key": "MySuperSecretKey123"
  • Token is digitally signed using this key
  • API uses the same key to verify

👉 This ensures: Token was not modified

Real-life analogy:

Think of it like: A sealed envelope with a signature stamp

If seal is broken → reject If seal matches → accept

Validation:

ValidateIssuerSigningKey = true

API verifies: “Is this token original and not tampered?”

4. Token Expiry (Lifetime)

ValidateLifetime = true
  • Token valid for 1 hour
  • After that → expired

Real-life analogy:

Movie ticket — Valid for 3 PM show At 6 PM → invalid

API checks: “Is token still valid?”

Complete Authentication Flow

Here’s how everything works together:

Step 1: User Logs In

The authentication server generates a token:


{
  "iss": "https://auth.mycompany.com",
  "aud": "employee-api",
  "sub": "12345",
  "role": "Employee"
}

Step 2: Frontend Sends Request


GET /api/profile
Authorization: Bearer <token>

Step 3: API Validates the Token

The API checks:

  • Issuer matches
  • Audience matches
  • Signature is valid
  • Token is not expired

If all validations pass:

Access is granted.

The Power of [Authorize]

Once JWT authentication is configured, protecting endpoints becomes incredibly simple.


[Authorize]
[HttpGet("secure-data")]
public IActionResult GetSecureData()
{
    return Ok("This is protected data.");
}

The [Authorize] attribute automatically:

  • Verifies authentication
  • Validates the JWT token
  • Blocks anonymous requests
  • Prevents unauthorized access

For me, adding [Authorize] was the moment the API truly became secure.

Final Thoughts

Implementing JWT authentication and ASP.NET Core’s [Authorize] attribute significantly improved the security of my APIs. The setup was relatively simple, highly scalable, and perfectly suited for modern web applications.

The biggest lesson I learned was that authentication alone isn’t enough. A secure API design should include multiple layers of protection — from API gateways to backend authorization checks.

If you’re building ASP.NET Core APIs that are consumed by React, Angular, mobile apps, or microservices, JWT authentication combined with [Authorize] is one of the most effective security approaches you can adopt.


메타데이터
post_id
b46f2bda1721
slug
how-i-secured-my-asp-net-core-apis-using-jwt-and-authorize-real-world-guide-b46f2bda1721
url
https://medium.com/@chandjogani93/how-i-secured-my-asp-net-core-apis-using-jwt-and-authorize-real-world-guide-b46f2bda1721
canonical_url
https://medium.com/@chandjogani93/how-i-secured-my-asp-net-core-apis-using-jwt-and-authorize-real-world-guide-b46f2bda1721
author_url
https://medium.com/@chandjogani93
status
ok
fetched_at
2026-07-15 16:48:10