← Back to Articles         
Angular Send a JWT to ASP.NET Core

Angular Send a JWT to ASP.NET Core

Published on 01 Oct 2026     8 min read Angular
Authentication

1. How Does Angular Send a JWT to ASP.NET Core?

What is it?

After a successful login, Angular receives a JWT from the ASP.NET Core Web API.

For subsequent protected API calls, Angular sends the JWT in the standard HTTP Authorization header using the Bearer scheme:

Authorization: Bearer <JWT_TOKEN>

For example:

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

Normally, an Angular HTTP interceptor automatically attaches the JWT to outgoing API requests.


Full Simple Angular Program

auth.service.ts

This service logs in and stores the returned token.

import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { tap } from 'rxjs';

interface LoginResponse {
  token: string;
}

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private http = inject(HttpClient);

  login(username: string, password: string) {

    return this.http
      .post<LoginResponse>(
        'https://localhost:7001/api/auth/login',
        {
          username,
          password
        }
      )
      .pipe(
        tap(response => {

          localStorage.setItem(
            'token',
            response.token
          );

        })
      );
  }

  getToken(): string | null {

    return localStorage.getItem('token');

  }

  logout(): void {

    localStorage.removeItem('token');

  }
}

auth.interceptor.ts

The interceptor automatically adds the JWT.

import {
  HttpInterceptorFn
} from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn =
  (req, next) => {

    const token =
      localStorage.getItem('token');

    if (token) {

      const authRequest =
        req.clone({

          setHeaders: {

            Authorization:
              `Bearer ${token}`

          }

        });

      return next(authRequest);
    }

    return next(req);
  };

app.config.ts

Register the interceptor:

import {
  ApplicationConfig
} from '@angular/core';

import {
  provideHttpClient,
  withInterceptors
} from '@angular/common/http';

import {
  authInterceptor
} from './auth.interceptor';

export const appConfig: ApplicationConfig = {

  providers: [

    provideHttpClient(
      withInterceptors([
        authInterceptor
      ])
    )

  ]

};

product.service.ts

import {
  inject,
  Injectable
} from '@angular/core';

import {
  HttpClient
} from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private http = inject(HttpClient);

  private apiUrl =
    'https://localhost:7001/api/products';


  getProducts() {

    return this.http.get(this.apiUrl);

  }
}

Notice that ProductService doesn't manually add the JWT.

We only write:

return this.http.get(this.apiUrl);

The interceptor handles authentication automatically.


How Angular Sends the JWT

Suppose Angular executes:

this.http.get(
  'https://localhost:7001/api/products'
);

Step 1 — Request enters interceptor

ProductService
      ↓
HttpClient
      ↓
Auth Interceptor

Step 2 — Interceptor gets token

const token =
  localStorage.getItem('token');

For example:

eyJhbGciOiJIUzI1NiIs...

Step 3 — Interceptor clones request

Angular HTTP requests are immutable, so we create a modified copy:

const authRequest =
  req.clone({
    setHeaders: {
      Authorization:
        `Bearer ${token}`
    }
  });

Step 4 — Actual request

The browser sends:

GET https://localhost:7001/api/products
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

So the flow is:

Angular Component
       ↓
ProductService
       ↓
HttpClient
       ↓
Auth Interceptor
       ↓
Get JWT
       ↓
Add Authorization Header
       ↓
ASP.NET Core Web API

2. How Does ASP.NET Core Validate a JWT?

What is it?

ASP.NET Core receives the JWT from:

Authorization: Bearer <token>

The JWT Bearer authentication handler extracts and validates the token.

It typically verifies:

Signature
Issuer
Audience
Expiration

If validation succeeds, ASP.NET Core creates an authenticated ClaimsPrincipal and stores it in:

HttpContext.User

Full Simple ASP.NET Core Configuration

appsettings.json

{
  "Jwt": {
    "Key": "ThisIsMySuperSecretKeyForJwtAuthentication12345",
    "Issuer": "MyWebApi",
    "Audience": "MyAngularApp"
  }
}

For production, the signing secret should be kept in an appropriate secret store rather than committed to configuration files.


Program.cs

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();


// Get JWT configuration

var jwtKey =
    builder.Configuration["Jwt:Key"]!;

var jwtIssuer =
    builder.Configuration["Jwt:Issuer"]!;

var jwtAudience =
    builder.Configuration["Jwt:Audience"]!;


// Configure authentication

builder.Services
    .AddAuthentication(
        JwtBearerDefaults.AuthenticationScheme
    )
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters =
            new TokenValidationParameters
            {
                ValidateIssuer = true,

                ValidateAudience = true,

                ValidateLifetime = true,

                ValidateIssuerSigningKey = true,


                ValidIssuer =
                    jwtIssuer,

                ValidAudience =
                    jwtAudience,

                IssuerSigningKey =
                    new SymmetricSecurityKey(
                        Encoding.UTF8.GetBytes(jwtKey)
                    )
            };
    });


// Configure authorization

builder.Services.AddAuthorization();


var app = builder.Build();

app.UseHttpsRedirection();


// Authentication first

app.UseAuthentication();


// Authorization second

app.UseAuthorization();


app.MapControllers();

app.Run();

ProductsController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace JwtDemo.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public IActionResult GetProducts()
    {
        var products = new[]
        {
            new
            {
                Id = 1,
                Name = "Laptop"
            },

            new
            {
                Id = 2,
                Name = "Mouse"
            }
        };

        return Ok(products);
    }
}

How ASP.NET Core Validates the JWT

Angular sends:

GET /api/products

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

ASP.NET Core processes it roughly like this:

HTTP Request
     ↓
Authorization Header
     ↓
Bearer Token
     ↓
JWT Bearer Authentication Handler
     ↓
Validate Token
     ↓
Create ClaimsPrincipal
     ↓
HttpContext.User
     ↓
Authorization
     ↓
[Authorize]
     ↓
Controller

Let's examine the important validations.


1. Validate Signature

Configuration:

ValidateIssuerSigningKey = true

and:

IssuerSigningKey =
    new SymmetricSecurityKey(
        Encoding.UTF8.GetBytes(jwtKey)
    );

This verifies that the token has a valid cryptographic signature from a trusted key.

Conceptually:

JWT received
     ↓
Validate signature
     ↓
Trusted signing key?
     ↓
Yes → Continue
No  → Reject

If somebody changes the token payload, such as changing:

Role = User

to:

Role = Admin

without being able to create a valid new signature, validation fails.


2. Validate Issuer

ValidateIssuer = true;

ValidIssuer = "MyWebApi";

Issuer answers:

Who issued this token?

The JWT might contain:

iss = MyWebApi

ASP.NET Core compares it with:

MyWebApi

If they don't match, validation fails.


3. Validate Audience

ValidateAudience = true;

ValidAudience = "MyAngularApp";

Audience answers:

Who is this token intended for?

The token might contain:

aud = MyAngularApp

ASP.NET Core checks it against the configured acceptable audience.


4. Validate Expiration

ValidateLifetime = true;

Suppose the JWT was generated with:

expires:
    DateTime.UtcNow.AddMinutes(30)

After the expiration time:

JWT
 ↓
Check expiration
 ↓
Expired
 ↓
Authentication fails
 ↓
401 Unauthorized

5. ASP.NET Core Creates HttpContext.User

If validation succeeds, ASP.NET Core constructs a ClaimsPrincipal.

For example, the token may contain claims corresponding to:

Name = admin
Role = Admin

ASP.NET Core makes them available through:

HttpContext.User

For example:

var username =
    User.Identity?.Name;

You can also inspect claims:

var claims =
    User.Claims.ToList();

6. [Authorize] Checks Authentication

The controller has:

[Authorize]

So:

Valid JWT
   ↓
Authenticated ClaimsPrincipal
   ↓
[Authorize]
   ↓
Controller executes

If authentication is missing or invalid:

Missing / Invalid JWT
        ↓
No authenticated user
        ↓
[Authorize]
        ↓
401 Unauthorized

Role-Based Authorization

Suppose your JWT contains:

Role = Admin

You can protect an endpoint:

[Authorize(Roles = "Admin")]
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
    return Ok();
}

Now the flow becomes:

Validate JWT
     ↓
Authenticated?
     ↓
YES
     ↓
Check Role = Admin
     ↓
YES ─────────→ Controller
     ↓
     NO
     ↓
403 Forbidden

This illustrates the distinction between authentication and authorization.


Complete End-to-End Flow

┌──────────────────────────┐
│         Angular          │
│                          │
│ ProductService           │
└────────────┬─────────────┘
             │
             ▼
       HttpClient
             │
             ▼
     Auth Interceptor
             │
             │ Read JWT
             │
             ▼
 Authorization:
 Bearer <JWT>
             │
             ▼
┌──────────────────────────┐
│ ASP.NET Core Web API     │
│                          │
│ JWT Bearer Authentication│
└────────────┬─────────────┘
             │
             ├── Signature ✓
             │
             ├── Issuer ✓
             │
             ├── Audience ✓
             │
             └── Lifetime ✓
             │
             ▼
      HttpContext.User
             │
             ▼
       Authorization
             │
             ▼
        [Authorize]
             │
             ▼
     ProductsController
             │
             ▼
          200 OK

Important: Who Does What?

Operation Angular ASP.NET Core
Receive JWT after login ✓  
Store/manage token on client ✓  
Attach JWT to request ✓  
Use Bearer header ✓  
Read Bearer JWT from request   ✓
Validate signature   ✓
Validate issuer   ✓
Validate audience   ✓
Validate expiration   ✓
Create HttpContext.User   ✓
Apply [Authorize]   ✓
Enforce roles/policies   ✓

The easiest way to remember this is:

Angular
   ↓
SEND JWT

ASP.NET Core
   ↓
VALIDATE JWT

Key Points

  • Angular normally sends JWT through the HTTP Authorization header.
  • The standard format is:
Authorization: Bearer <JWT>
  • An Angular HTTP interceptor is commonly used so every API service doesn't have to manually add the token.
  • ASP.NET Core's JWT Bearer authentication handler performs server-side token validation.
  • Common validation includes signature, issuer, audience, and lifetime.
  • After successful authentication, claims are available through HttpContext.User.
  • [Authorize] protects endpoints.
  • [Authorize(Roles = "Admin")] adds role-based authorization.
  • Missing/invalid authentication normally produces 401 Unauthorized.
  • An authenticated user without the required authorization normally receives 403 Forbidden.
  • Angular route guards and UI checks are useful for UX, but the ASP.NET Core API must enforce actual security.

Interview Questions & Answers

1. How does Angular send JWT to ASP.NET Core?

Angular sends the JWT in the HTTP Authorization header using the Bearer scheme:

Authorization: Bearer <token>

An HTTP interceptor is commonly used to attach it automatically.

2. Why do we use an Angular interceptor for JWT?

It centralizes token attachment. Instead of adding the Authorization header in every API service, the interceptor automatically adds it to appropriate outgoing requests.

3. How does ASP.NET Core validate a JWT?

ASP.NET Core's JWT Bearer authentication handler reads the Bearer token and validates its signature, issuer, audience, and lifetime according to TokenValidationParameters.

4. What is AddJwtBearer()?

.AddJwtBearer(...)

configures JWT Bearer authentication in ASP.NET Core, including how incoming access tokens should be validated.

5. What is TokenValidationParameters?

It specifies the token validation rules, for example:

ValidateIssuer = true;
ValidateAudience = true;
ValidateLifetime = true;
ValidateIssuerSigningKey = true;

6. What happens after successful JWT validation?

ASP.NET Core creates an authenticated ClaimsPrincipal and assigns it to:

HttpContext.User

Authorization can then evaluate the user's claims, roles, and policies.

7. What happens when the JWT is expired?

With:

ValidateLifetime = true

an expired token fails authentication, and a protected endpoint normally returns:

401 Unauthorized

8. What is the difference between UseAuthentication() and UseAuthorization()?

app.UseAuthentication();

establishes who the user is from the configured authentication mechanism.

app.UseAuthorization();

determines whether that user is allowed to access the requested resource.

9. Which should come first?

Authentication should precede authorization:

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

Conceptually:

Authentication
"Who are you?"
      ↓
Authorization
"What are you allowed to do?"

Interview Quick Answer

Angular sends the JWT in the Authorization: Bearer <token> header, usually through an HTTP interceptor. ASP.NET Core's JWT Bearer authentication handler extracts the token, validates its signature, issuer, audience, and expiration, creates the authenticated ClaimsPrincipal, and then authorization rules such as [Authorize], roles, claims, or policies determine whether the request can access the endpoint.

← Back to Articles