Reputation: 410
Getting this error when accessing from browser
Access to XMLHttpRequest at 'https://api.example.com/users/authenticate' from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
Startup.cs
using System;
using System.Text;
using BackendRest.Helper;
using BackendRest.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
namespace BackendRest
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
readonly string CorsApi = "_CorsApi";
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(CorsApi,
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
services.AddControllers().AddNewtonsoftJson();
services.AddDbContext<backenddbContext>(x => x.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
services.AddScoped<IUserHelper, UserHelper>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ClockSkew = TimeSpan.Zero,
ValidateLifetime = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["Jwt:Audience"],
ValidIssuer = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(CorsApi);
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Nginx Conf File
server {
#listen 80;
listen *:443 ssl;
ssl_certificate /etc/ssl/example.com.pem;
ssl_certificate_key /etc/ssl/example.com.key;
if ($host != "api.example.com") {
return 404;
}
server_name api.example.com;
location / {
proxy_pass https://localhost:5001;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Have enabled Cors Policy in the controllers also By adding bellow code to controller top
[EnableCors("CorsApi")]
Function for sending request in frontend:
export const login = async ({ username, password }) => {
const result = await axios.post(
`${BASE_URL}/users/authenticate`,
JSON.stringify({ username, password }),
{
headers: {
'Content-Type': 'application/json',
},
}
);
return result;
};
Startup Setting for locahost server:
"Kestrel": {
"Endpoints": {
"HTTPS": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "/etc/ssl/example.pfx",
"Password": "james343"
}
}
}
}
Service Starting the Locahost Server:
[Unit]
Description=My first .NET Core application on Ubuntu
[Service]
WorkingDirectory=/home/ubuntu/example
ExecStart=/usr/bin/dotnet /home/ubuntu/example/BackendRest.dll
Restart=always
RestartSec=10 # Restart service after 10 seconds if dotnet service crashes
SyslogIdentifier=offershare-web-app
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
Environment=ASPNETCORE_HTTPS_PORT=5001
Environment=ASPNETCORE_URLS=https://localhost:5001
[Install]
WantedBy=multi-user.target
Can anyone please point it out where i am going wrong bit new the nginx stuff whereas another project when hosted with normal iis all works good.
Upvotes: 4
Views: 18609
Reputation: 1998
h have same problem : without add header to nginx can solve it :
nginx config:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
add this line to program.cs(.net core 6) or startup.cs (.net core 3.1 or 5):
//CORS configuration
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
//Auth... configuration
this make proxy to forward all headers and not need to add headers on nginx again.
Upvotes: 0
Reputation: 15662
I don't know if the CORS headers could be added from the .NET application itself, or is that one approach is better, but to add them via nginx you can use the following:
server {
...
location / {
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Content-Type text/plain;
add_header Content-Length 0;
return 204;
}
... # your current configuration here
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
}
}
If you need to support additional methods (PUT
, DELETE
, etc.), add them to the methods list.
Update
If your XMLHttpRequest is being made with credentials, you cannot use *
as the Access-Control-Allow-Origin
header value. For that case you can dynamically set the Access-Control-Allow-Origin
to the request's Origin
header value:
server {
...
location / {
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Content-Type text/plain;
add_header Content-Length 0;
return 204;
}
... # your current configuration here
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
}
}
Upvotes: 10