最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

SignalR - .NET Core 6.0 working in local and failing with cors error once deployed - Stack Overflow

programmeradmin4浏览0评论

I am implementing simple signal R real-time messaging. It works absolutely fine in local but moment its deployed i get CORS error

8DUpdate.html:1 Access to fetch at '' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.Understand this errorAI signalr.min.js:1

Preflight request :

Request URL: Request Method: OPTIONS Status Code: 405 Not Allowed Remote Address: 10.11.111.4:443 Referrer Policy: strict-origin-when-cross-origin

I tried allowing specific origins, all origins and every possible CORS related options i found. I doubt i am messing up with the order somewhere?

Below is Program.cs code

using System.IdentityModel.Tokens.Jwt;
using DotNetSmartLogger;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.OpenApi.Models;
using NLog;
using NLog.Web;
using Quality.EightD.API;
using Quality.EightD.API.Behaviour;
using Quality.EightD.API.ChatHub;

var builder = WebApplication.CreateBuilder(args);

// QA Appsetting testing
//builder.Configuration
//    .AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true);

// Add services to the container.

builder
    .Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
    });
builder
    .Services.AddSignalR(hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(15); // Reduce from 1 minute
        hubOptions.ClientTimeoutInterval = TimeSpan.FromSeconds(30); // Reduce from 2 minutes
        hubOptions.HandshakeTimeout = TimeSpan.FromSeconds(15); // Add handshake timeout
        hubOptions.MaximumReceiveMessageSize = 102400; // Increased to 100KB
        hubOptions.StreamBufferCapacity = 10;
    })
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    });

builder.Services.AddCors(options =>
{
    options.AddPolicy(
        "CORSPolicy",
        builder =>
        {
            builder
                .WithOrigins("http://localhost:8080", ";)
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials();
        }
    );
});

// Learn more about configuring Swagger/OpenAPI at 
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.ConfigureRepositories();
builder.Services.AddSwaggerGen(setup =>
{
    // Include 'SecurityScheme' to use JWT Authentication
    var jwtSecurityScheme = new OpenApiSecurityScheme
    {
        Scheme = "bearer",
        BearerFormat = "JWT",
        Name = "JWT Authentication",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Description = "Put **_ONLY_** your JWT Bearer token on textbox below!",
        Reference = new OpenApiReference
        {
            Id = JwtBearerDefaults.AuthenticationScheme,
            Type = ReferenceType.SecurityScheme,
        },
    };
    setup.SwaggerDoc("v1", new OpenApiInfo { Title = "Quality.EightD.API", Version = "v1" });
    setup.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme);
    setup.AddSecurityRequirement(
        new OpenApiSecurityRequirement { { jwtSecurityScheme, Array.Empty<string>() } }
    );
});

// Configure smart logger
builder.Services.AddLogging(loggingBuilder =>
{
    loggingBuilder.ClearProviders();
    loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
    loggingBuilder.AddNLogWeb();
});

// Configure Kestrel server options
builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.MaxRequestBodySize = long.MaxValue; // if don't set default value is: 30 MB
});

// Configure form options
builder.Services.Configure<FormOptions>(o =>
{
    o.ValueLengthLimit = int.MaxValue;
    o.MultipartBodyLengthLimit = int.MaxValue;
    o.MultipartBoundaryLengthLimit = int.MaxValue;
    o.MultipartHeadersCountLimit = int.MaxValue;
    o.MultipartHeadersLengthLimit = int.MaxValue;
    o.BufferBodyLengthLimit = int.MaxValue;
    o.BufferBody = true;
    o.ValueCountLimit = int.MaxValue;
});

builder.Services.AddHttpContextAccessor();

// Configure JWT Authentication
builder
    .Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                var accessToken = context.Request.Query["access_token"];
                var path = context.HttpContext.Request.Path;
                if (
                    (
                        !string.IsNullOrEmpty(accessToken)
                        || context.Request.Headers.ContainsKey("Authorization")
                    ) && path.StartsWithSegments("/chatHub")
                )
                {
                    context.Token = accessToken;
                }
                return Task.CompletedTask;
            },
        };
        options.RequireHttpsMetadata = false; // For development - set to true in production
        options.SaveToken = true;
    });

var app = builder.Build();

// Configure Swagger
app.UseSwagger(c =>
{
    c.RouteTemplate = "eightd-api-svc/{documentName}/swagger.json";
});

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/eightd-api-svc/v1/swagger.json", "API Service V1");
    c.RoutePrefix = "eightd-api-svc";
    c.ConfigObject.AdditionalItems["syntaxHighlight"] = new Dictionary<string, object>
    {
        ["activated"] = false,
    };
});

LogManager.Configuration.Variables["logPath"] = builder.Configuration.GetValue<string>("logPath");

// Update the order of middleware
// First, essential middleware
app.UseRouting();
app.UseCors("CORSPolicy");
app.UseAuthentication();
app.UseAuthorization();

// Add buffering middleware early in the pipeline
app.Use(
    async (context, next) =>
    {
        // Enable buffering for all requests
        context.Request.EnableBuffering();
        await next();
    }
);

// Then your custom middleware
app.UseMiddleware<JwtAuthenticationBehaviour>();
app.UseMiddleware<ResponseMiddleware>();
app.UseMiddleware<NLogRequestPostedBodyMiddleware>();
app.UseMiddleware<SmartLoggingMiddleware>();
app.UseMiddleware<ExceptionHandlingMiddleware>();

// Finally endpoints
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapHub<ChatHub>("/chatHub");
});

app.UseHttpsRedirection();
app.MapControllers();

app.Run();

I am implementing simple signal R real-time messaging. It works absolutely fine in local but moment its deployed i get CORS error

8DUpdate.html:1 Access to fetch at 'https://test.test.test/chatHub/negotiate?negotiateVersion=1' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.Understand this errorAI signalr.min.js:1

Preflight request :

Request URL: https://test.test.test/chatHub/negotiate?negotiateVersion=1 Request Method: OPTIONS Status Code: 405 Not Allowed Remote Address: 10.11.111.4:443 Referrer Policy: strict-origin-when-cross-origin

I tried allowing specific origins, all origins and every possible CORS related options i found. I doubt i am messing up with the order somewhere?

Below is Program.cs code

using System.IdentityModel.Tokens.Jwt;
using DotNetSmartLogger;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.OpenApi.Models;
using NLog;
using NLog.Web;
using Quality.EightD.API;
using Quality.EightD.API.Behaviour;
using Quality.EightD.API.ChatHub;

var builder = WebApplication.CreateBuilder(args);

// QA Appsetting testing
//builder.Configuration
//    .AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true);

// Add services to the container.

builder
    .Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
    });
builder
    .Services.AddSignalR(hubOptions =>
    {
        hubOptions.EnableDetailedErrors = true;
        hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(15); // Reduce from 1 minute
        hubOptions.ClientTimeoutInterval = TimeSpan.FromSeconds(30); // Reduce from 2 minutes
        hubOptions.HandshakeTimeout = TimeSpan.FromSeconds(15); // Add handshake timeout
        hubOptions.MaximumReceiveMessageSize = 102400; // Increased to 100KB
        hubOptions.StreamBufferCapacity = 10;
    })
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    });

builder.Services.AddCors(options =>
{
    options.AddPolicy(
        "CORSPolicy",
        builder =>
        {
            builder
                .WithOrigins("http://localhost:8080", "https://test.test.test")
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials();
        }
    );
});

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.ConfigureRepositories();
builder.Services.AddSwaggerGen(setup =>
{
    // Include 'SecurityScheme' to use JWT Authentication
    var jwtSecurityScheme = new OpenApiSecurityScheme
    {
        Scheme = "bearer",
        BearerFormat = "JWT",
        Name = "JWT Authentication",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Description = "Put **_ONLY_** your JWT Bearer token on textbox below!",
        Reference = new OpenApiReference
        {
            Id = JwtBearerDefaults.AuthenticationScheme,
            Type = ReferenceType.SecurityScheme,
        },
    };
    setup.SwaggerDoc("v1", new OpenApiInfo { Title = "Quality.EightD.API", Version = "v1" });
    setup.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme);
    setup.AddSecurityRequirement(
        new OpenApiSecurityRequirement { { jwtSecurityScheme, Array.Empty<string>() } }
    );
});

// Configure smart logger
builder.Services.AddLogging(loggingBuilder =>
{
    loggingBuilder.ClearProviders();
    loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
    loggingBuilder.AddNLogWeb();
});

// Configure Kestrel server options
builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.MaxRequestBodySize = long.MaxValue; // if don't set default value is: 30 MB
});

// Configure form options
builder.Services.Configure<FormOptions>(o =>
{
    o.ValueLengthLimit = int.MaxValue;
    o.MultipartBodyLengthLimit = int.MaxValue;
    o.MultipartBoundaryLengthLimit = int.MaxValue;
    o.MultipartHeadersCountLimit = int.MaxValue;
    o.MultipartHeadersLengthLimit = int.MaxValue;
    o.BufferBodyLengthLimit = int.MaxValue;
    o.BufferBody = true;
    o.ValueCountLimit = int.MaxValue;
});

builder.Services.AddHttpContextAccessor();

// Configure JWT Authentication
builder
    .Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                var accessToken = context.Request.Query["access_token"];
                var path = context.HttpContext.Request.Path;
                if (
                    (
                        !string.IsNullOrEmpty(accessToken)
                        || context.Request.Headers.ContainsKey("Authorization")
                    ) && path.StartsWithSegments("/chatHub")
                )
                {
                    context.Token = accessToken;
                }
                return Task.CompletedTask;
            },
        };
        options.RequireHttpsMetadata = false; // For development - set to true in production
        options.SaveToken = true;
    });

var app = builder.Build();

// Configure Swagger
app.UseSwagger(c =>
{
    c.RouteTemplate = "eightd-api-svc/{documentName}/swagger.json";
});

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/eightd-api-svc/v1/swagger.json", "API Service V1");
    c.RoutePrefix = "eightd-api-svc";
    c.ConfigObject.AdditionalItems["syntaxHighlight"] = new Dictionary<string, object>
    {
        ["activated"] = false,
    };
});

LogManager.Configuration.Variables["logPath"] = builder.Configuration.GetValue<string>("logPath");

// Update the order of middleware
// First, essential middleware
app.UseRouting();
app.UseCors("CORSPolicy");
app.UseAuthentication();
app.UseAuthorization();

// Add buffering middleware early in the pipeline
app.Use(
    async (context, next) =>
    {
        // Enable buffering for all requests
        context.Request.EnableBuffering();
        await next();
    }
);

// Then your custom middleware
app.UseMiddleware<JwtAuthenticationBehaviour>();
app.UseMiddleware<ResponseMiddleware>();
app.UseMiddleware<NLogRequestPostedBodyMiddleware>();
app.UseMiddleware<SmartLoggingMiddleware>();
app.UseMiddleware<ExceptionHandlingMiddleware>();

// Finally endpoints
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapHub<ChatHub>("/chatHub");
});

app.UseHttpsRedirection();
app.MapControllers();

app.Run();
Share Improve this question edited Mar 21 at 0:38 Ishan asked Mar 20 at 23:32 IshanIshan 4,02832 gold badges95 silver badges157 bronze badges 6
  • Please try to comment this line //app.UseHttpsRedirection();, then check again. – Jason Commented Mar 21 at 2:26
  • May I know where you host the application, IIS or others? If you are using IIS, could you kindly check URL Rewrite module is installed or not, thanks~ – Jason Commented Mar 21 at 4:46
  • This service is hosted on ARO. – Ishan Commented Mar 21 at 5:28
  • Hi Ishan, what is ARO ? Could you share me the link ? – Jason Commented Mar 21 at 6:22
  • Sorry, its Azure Red Hat OpenShift. – Ishan Commented Mar 21 at 18:22
 |  Show 1 more comment

1 Answer 1

Reset to default 0

Issue :

// Finally endpoints
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapHub<ChatHub>("/chatHub");
});

Fix :

// Finally endpoints
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapHub<ChatHub>("eightd-api-svc/chatHub");
});
发布评论

评论列表(0)

  1. 暂无评论