1. What is CORS?
What is CORS?
CORS stands for Cross-Origin Resource Sharing.
CORS is a browser security mechanism that controls whether JavaScript running from one origin is allowed to access resources from another origin.
For example:
Angular
http://localhost:4200
↓ HTTP Request
ASP.NET Core Web API
https://localhost:7001
These are different origins, so the browser applies CORS rules.
CORS allows the server to explicitly tell the browser which origins, HTTP methods, and headers are permitted for cross-origin requests.
What is an Origin?
An origin consists of:
Scheme + Host + Port
For example:
http://localhost:4200
contains:
Scheme = http
Host = localhost
Port = 4200
Two URLs have the same origin only when all three relevant components match.
Example
http://localhost:4200
http://localhost:4200
Same origin.
But:
http://localhost:4200
https://localhost:7001
Different origin because:
Scheme differs
Port differs
Even these are different origins:
http://localhost:4200
http://localhost:5000
because the port is different.
Full Simple Angular + ASP.NET Core Example
Assume:
Angular:
http://localhost:4200
ASP.NET Core:
https://localhost:7001
Angular — 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
);
}
}
Angular makes:
GET https://localhost:7001/api/products
But Angular itself is running from:
http://localhost:4200
Therefore:
Origin of Angular
↓
http://localhost:4200
Origin of API
↓
https://localhost:7001
Different Origins
↓
CORS rules apply
ASP.NET Core CORS Configuration
Program.cs
var builder =
WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddCors(options =>
{
options.AddPolicy(
"AngularApp",
policy =>
{
policy
.WithOrigins(
"http://localhost:4200"
)
.AllowAnyHeader()
.AllowAnyMethod();
});
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseCors("AngularApp");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
The important configuration is:
.WithOrigins(
"http://localhost:4200"
)
This tells ASP.NET Core:
Requests originating from
http://localhost:4200are allowed by this CORS policy.
Products Controller
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class ProductsController
: ControllerBase
{
[HttpGet]
public IActionResult Get()
{
var products = new[]
{
new
{
Id = 1,
Name = "Laptop"
},
new
{
Id = 2,
Name = "Mouse"
}
};
return Ok(products);
}
}
Now Angular can call:
https://localhost:7001/api/products
from:
http://localhost:4200
provided the CORS policy permits it.
How CORS Works
Angular makes a request:
GET /api/products
Origin: http://localhost:4200
The browser includes the origin.
ASP.NET Core's CORS middleware evaluates:
http://localhost:4200
against the configured policy:
.WithOrigins(
"http://localhost:4200"
)
If allowed, the API response can contain a header such as:
Access-Control-Allow-Origin: http://localhost:4200
The browser sees that response and allows Angular JavaScript to access it.
CORS Flow
Angular
http://localhost:4200
│
│ Request
│
│ Origin:
│ http://localhost:4200
▼
ASP.NET Core
https://localhost:7001
│
▼
CORS Middleware
│
│ Is Angular origin allowed?
│
┌─┴─┐
Yes No
│ │
▼ ▼
CORS Not permitted
headers for browser access
│
▼
Browser
│
▼
Angular receives response
2. Why Does CORS Occur Between Angular and ASP.NET Core?
Because Angular and ASP.NET Core commonly run on different origins.
During development, you might have:
Angular
http://localhost:4200
ASP.NET Core
https://localhost:7001
Compare them:
| Part | Angular | ASP.NET Core |
|---|---|---|
| Scheme | http |
https |
| Host | localhost |
localhost |
| Port | 4200 |
7001 |
Therefore:
Angular Origin
http://localhost:4200
≠
API Origin
https://localhost:7001
The browser treats this as a cross-origin request.
Why Does the Browser Care?
Browsers enforce the Same-Origin Policy.
The same-origin policy restricts JavaScript from freely reading data from unrelated origins.
Without such restrictions, a malicious website could potentially try to interact with other sites the user is authenticated to.
CORS provides a controlled way for the target server to say:
"I permit browser JavaScript from these specific origins to access my responses."
Example Without CORS
Angular:
http://localhost:4200
calls:
https://localhost:7001/api/products
But ASP.NET Core doesn't return appropriate CORS headers.
The browser may report an error similar to:
Access to XMLHttpRequest at
'https://localhost:7001/api/products'
from origin
'http://localhost:4200'
has been blocked by CORS policy.
An important detail:
A CORS error does not necessarily mean the API endpoint itself failed. The browser may be refusing to expose the response to the Angular application.
Simple Requests vs Preflight Requests
This is another important CORS concept.
Some cross-origin requests require the browser to first send a preflight request.
The preflight uses:
OPTIONS
For example, Angular wants to send:
DELETE /api/products/10
Authorization: Bearer <JWT>
The browser may first send:
OPTIONS /api/products/10
Origin: http://localhost:4200
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: authorization
ASP.NET Core responds indicating what is allowed, for example:
Access-Control-Allow-Origin: http://localhost:4200
Access-Control-Allow-Methods: DELETE
Access-Control-Allow-Headers: authorization
Then the browser can proceed with the actual request if the preflight succeeds.
Why JWT Requests Commonly Trigger Preflight
Your Angular interceptor may add:
Authorization: Bearer <JWT>
For example:
const authRequest =
req.clone({
setHeaders: {
Authorization:
`Bearer ${token}`
}
});
Because Authorization is not a CORS-safelisted request header, a cross-origin request using it commonly requires a preflight.
So you may see:
Angular
↓
OPTIONS request
↓
ASP.NET Core CORS check
↓
Preflight succeeds
↓
Actual GET/POST/PUT/DELETE
↓
Authorization: Bearer JWT
AllowAnyHeader()
This configuration:
.AllowAnyHeader()
allows request headers permitted by the policy, including headers such as:
Authorization
Content-Type
For a JWT-based Angular application, this is relevant because Angular commonly sends:
Authorization: Bearer <token>
You can also configure headers more narrowly when appropriate.
AllowAnyMethod()
.AllowAnyMethod()
allows methods such as:
GET
POST
PUT
DELETE
PATCH
Again, a production policy should grant only what the frontend actually requires where practical.
AllowAnyOrigin()
You may encounter:
.AllowAnyOrigin()
This effectively allows any origin under that policy.
For APIs intended only for your Angular application, a more restrictive configuration is usually preferable:
.WithOrigins(
"https://www.example.com"
)
rather than:
.AllowAnyOrigin()
Development vs Production
During development:
.WithOrigins(
"http://localhost:4200"
)
Production might use:
.WithOrigins(
"https://www.jntech.in"
)
Or multiple trusted origins:
.WithOrigins(
"https://www.jntech.in",
"https://admin.jntech.in"
)
The important idea is to explicitly permit the frontend origins that actually need browser access.
CORS with Cookies
If Angular and ASP.NET Core use cross-origin cookies, additional configuration may be required.
Angular:
this.http.get(
apiUrl,
{
withCredentials: true
}
);
ASP.NET Core:
policy
.WithOrigins(
"https://www.example.com"
)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
When credentials are allowed, you cannot combine:
.AllowAnyOrigin()
with:
.AllowCredentials()
Instead, explicitly specify trusted origins.
CORS Is Not Authentication
This is a very important distinction.
CORS:
Which browser origins may access
the API response?
Authentication:
Who is the user?
Authorization:
What can the user do?
Therefore:
CORS
≠
Authentication
≠
Authorization
Even if you configure:
.WithOrigins(
"https://www.example.com"
)
you still need:
[Authorize]
for protected endpoints.
CORS Does Not Prevent Direct API Calls
CORS is primarily enforced by web browsers.
It should not be treated as a mechanism that makes an API inaccessible to non-browser clients.
For example:
Angular Browser
↓
CORS applies
Postman / server application
↓
Not relying on browser CORS enforcement
Therefore:
Never use CORS as your API security mechanism.
Your actual API security comes from authentication and authorization.
Complete Angular + ASP.NET Core Flow
Angular
http://localhost:4200
│
│ Cross-Origin Request
▼
Browser
│
│ Apply CORS rules
│
│ OPTIONS preflight
│ if required
▼
ASP.NET Core
https://localhost:7001
│
▼
CORS Middleware
│
├── Origin allowed?
├── Method allowed?
└── Headers allowed?
│
▼
Authentication
│
▼
Validate JWT
│
▼
Authorization
│
▼
[Authorize]
│
▼
Controller
Notice the separation:
CORS
↓
Can this browser origin access it?
Authentication
↓
Who is the user?
Authorization
↓
Can this user perform this operation?
Key Points
- CORS = Cross-Origin Resource Sharing.
- It is a browser-enforced mechanism for controlling cross-origin access.
- An origin is based on scheme + host + port.
- Angular and ASP.NET Core commonly use different ports during development, so they are different origins.
- ASP.NET Core can configure CORS using:
builder.Services.AddCors(...)
- Apply the configured policy with:
app.UseCors(...)
- Use
WithOrigins()to specify trusted frontend origins. AllowAnyHeader()permits headers such asAuthorizationunder that policy.AllowAnyMethod()permits HTTP methods such as GET, POST, PUT, and DELETE.- Some requests cause an
OPTIONSpreflight request. - Bearer-token requests commonly trigger preflight because of the
Authorizationheader. - CORS is not authentication.
- CORS is not authorization.
- CORS does not replace
[Authorize]. - CORS should not be considered protection against direct non-browser API calls.
Interview Questions & Answers
1. What is CORS?
CORS stands for Cross-Origin Resource Sharing. It is a browser security mechanism that allows a server to specify which origins are permitted to access its resources from browser JavaScript.
2. Why does CORS occur between Angular and ASP.NET Core?
Because Angular and ASP.NET Core often run on different origins.
For example:
Angular
http://localhost:4200
ASP.NET Core
https://localhost:7001
Different scheme and/or port means different origin.
3. What defines an origin?
An origin consists of:
Scheme + Host + Port
For example:
https://localhost:7001
4. How do you enable CORS in ASP.NET Core?
Register a CORS policy:
builder.Services.AddCors(options =>
{
options.AddPolicy(
"AngularApp",
policy =>
{
policy
.WithOrigins(
"http://localhost:4200"
)
.AllowAnyHeader()
.AllowAnyMethod();
});
});
and apply it:
app.UseCors("AngularApp");
5. What is a CORS preflight request?
A preflight is an OPTIONS request that the browser may send before the actual cross-origin request to determine whether the requested origin, method, and headers are allowed.
OPTIONS
↓
CORS validation
↓
Actual request
6. Why does JWT authentication often involve CORS preflight?
Because Angular commonly sends:
Authorization: Bearer <JWT>
and the Authorization header generally causes a cross-origin request to require preflight.
7. Is CORS an authentication mechanism?
No.
CORS
→ Browser cross-origin access
Authentication
→ Who are you?
Authorization
→ What can you do?
8. Does CORS protect the API from Postman or other server-side clients?
No. CORS is primarily a browser security mechanism. API authentication and authorization must independently protect the API.
Interview Quick Answer
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that controls whether JavaScript from one origin can access resources from another origin. It commonly occurs between Angular and ASP.NET Core because Angular may run on
http://localhost:4200while the API runs onhttps://localhost:7001, making them different origins. ASP.NET Core must configure an appropriate CORS policy to explicitly allow the Angular application's origin.