当前位置: 首页 > 知识库问答 >
问题:

Angular应用程序无法与asp.net core的信号器安排进行协商。由于CORS错误

吴缪文
2023-03-14

我的statup.cs类代码如下:

namespace Tenet.eReserve.Api.WebApi
{
    public class Startup
    {
        public IConfiguration Configuration { get; }
        public string SuperSecret { get; set;  }
        public Startup(IConfiguration configuration) => Configuration = configuration;


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            services.AddSingleton<IConfiguration>(Configuration);
            services.Configure<Settings>(Configuration.GetSection("eReserve"));

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "eReserve API List", Version = "v1" });
                c.AddSecurityDefinition("Bearer",
                    new OpenApiSecurityScheme
                    {
                        Description = "JWT Authorization header using the Bearer scheme.",
                        Type = SecuritySchemeType.Http, //We set the scheme type to http since we're using bearer authentication
                        Scheme = "bearer"
                    });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement{
                    {
                        new OpenApiSecurityScheme{
                            Reference = new OpenApiReference{
                                Id = "Bearer", //The name of the previously defined security scheme.
                                Type = ReferenceType.SecurityScheme
                            }
                        },new List<string>()
                    }
                });

            });

            services.AddControllers().AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
            }).AddNewtonsoftJson(); // to convert string values to int32 and decimal   

            services.AddScoped<IReportService, ReportService>();
            services.AddScoped<ISearchService, SearchService>();


            var sp = services.BuildServiceProvider();

            // This will succeed.
            var settings = sp.GetService<IOptionsSnapshot<Settings>>();

            services.AddApplicationInsightsTelemetry(options =>
            {
                options.EnableDebugLogger = false;
            });
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder.WithOrigins(settings.Value.SignalROrigniURL) //http://localhost:8090")
                               .AllowAnyHeader()
                           .AllowAnyMethod()
                           .SetIsOriginAllowed((x) => true)
                           .AllowCredentials());

                //  options.AddPolicy("CorsPolicy",
                //                builder => builder.AllowAnyOrigin()
                //.AllowAnyMethod()
                //.AllowAnyHeader());
            });
            services.AddAuthentication(opt =>
            {
                opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(
            );
            services.ConfigureOptions<ConfigureJwtBearerOptions>();
            services.AddHttpContextAccessor();
            services.AddAuthorization(options =>
            {
                options.AddPolicy("HospitalCode", policy =>
                    policy.Requirements.Add(new HospitalCodeRequirement()));
            });
            services.AddSingleton<IAuthorizationHandler, FacilityHandler>();
            services.AddSignalR(options =>
            {
                options.EnableDetailedErrors = true;
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, TelemetryConfiguration configuration, IOptionsSnapshot<Settings> settings)
        {
   
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseAzureAppConfiguration();
            app.UseSwagger();
            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
            // specifying the Swagger JSON endpoint.
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "eReserve API V1");
                c.RoutePrefix = String.Empty;
            });
            configuration.InstrumentationKey = settings.Value.AppInsightsInstrumentationKey;
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseCors("CorsPolicy");
            app.UseAuthentication(); // this one first
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
           {
               endpoints.MapControllers();
               endpoints.MapHub<NotifyClientService>("/lockNotification");
           });
            //app.UseSignalR(routes =>
            //{
            //    routes.MapHub<NotifyClientService>("/lockNotification");
            //});
        }
    }
}

在角度上,我创造了这样的连接:

private hubConnection: signalR.HubConnection;

public startConnection = () => {
  this.hubConnection = new signalR.HubConnectionBuilder()
    .withUrl(this.apiBase + 'lockNotification')
    .build();
  this.hubConnection
    .start()
    .then(() => console.log('Connection started'))
    .catch(err => console.log('Error while starting connection: ' + err));
}

public startListener = () => {
  this.hubConnection.on('LockNotification', (facilityName, lockType, hospitalCode) => {
   //logic

    }
  });
}

此安排在本地工作,但部署时会导致CORS错误:

在'https://abc-api.com/lockNotification/negotiate?negotiateVersion=1“起源”https://abc-ui.com'已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:响应中的'access control Allow Credentials'标头的值为'',请求启动时该值必须为'true'凭据模式为“包括”。zone.js:1118 POSThttps://xxx-xxx.com/lockNotification/negotiate?negotiateVersion=1 net::ERR_失败

请注意,“settings.Value.signalRoIgnitUrl”返回https://abc-ui.com“(假网址)

使现代化

在ConfigureServices方法中,我有如下COR:

services.AddCors(options =>
{
    options.AddPolicy("CorsPolicy",
                  builder => builder.AllowAnyOrigin()
  .AllowAnyMethod()
  .AllowAnyHeader());
});

不确定是否需要上述内容,在配置中,我遵循了文档。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, TelemetryConfiguration configuration, IOptionsSnapshot<Settings> settings)
{
   
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseAzureAppConfiguration();
    app.UseSwagger();
    // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
    // specifying the Swagger JSON endpoint.
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "eReserve API V1");
        c.RoutePrefix = String.Empty;
    });
    configuration.InstrumentationKey = settings.Value.AppInsightsInstrumentationKey;
    app.UseHttpsRedirection();
    app.UseCors(builder =>
    {
        builder.WithOrigins(settings.Value.SignalROrigniURL)
            .AllowAnyHeader()
            .WithMethods("GET", "POST")
            .AllowCredentials();
    });
    app.UseRouting();
    app.UseAuthentication(); // this one first
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
   {
       endpoints.MapControllers();
       endpoints.MapHub<NotifyClientService>("/lockNotification");
   });
    //app.UseSignalR(routes =>
    //{
    //    routes.MapHub<NotifyClientService>("/lockNotification");
    //});
}

更新2

CORS还配置在部署API的位置。

共有1个答案

江航
2023-03-14

你好,你需要配置cors完全像我回答这个类似的问题:

services.AddCors(options =>
{
    options.AddPolicy("CorsPolicy", builder => builder.WithOrigins("http://localhost:4200")
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials()
        .SetIsOriginAllowed((host) => true));
});

我还建议删除Azure上的CORS配置,以便在服务器上测试CORS的代码。在后端正确配置CORS后,您将不需要更新2上的Azure CORS配置。

使现代化

启动时配置CORS的示例:

public void Configure(IApplicationBuilder app, HostConfiguration hostConfiguration, ILogger<Startup> logger)
{
    app.UseCors("CorsPolicy");
}

private static void AddCors(IServiceCollection services, HostConfiguration hostConfiguration)
{
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy", builder => builder.WithOrigins(hostConfiguration.CorsPolicy.Origins.ToArray())
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowCredentials()
            .SetIsOriginAllowed((host) => hostConfiguration.CorsPolicy.SetIsOriginAllowed));
    });
}

我调用addAdditionalServices方法上的私有addCors方法

 类似资料:
  • 当我尝试在华为P9上运行我的应用程序时,我得到了一个错误 日志: 07-04 10:42:56.045:W/System.err(955):java.lang.NullPoInterException:尝试对空对象引用调用虚拟方法“int com.huawie.lcagent.client.logCollectManager.GetUserType()”07-04 10:42:56.046:W/S

  • 我让spring boot应用程序在域A上运行。它的目的是公开一些RESTendpoint。 此外,我有角度8应用程序。它可以部署在同一个域A或其他域B中。spring boot应用程序知道应用程序部署在哪个域上。 我需要配置Spring Security性,因此它将仅接受来自角应用程序的特定endpoint上的请求。但是,一些endpoint需要了解角色 例如: /api/v1/resource

  • 我刚刚创建了一个新的模板与与reactv17包括,我安装了eslint依赖,因为我以前,这是我的package.json文件 这是我的eslintrc.json:(注意我还没有添加所有的规则) 当我运行应用程序时,由于以下错误,应用程序将无法编译: 我在以前的项目中工作过,代码中显示了eslint错误,但没有导致应用程序崩溃。有人能指出我把事情弄糟的地方吗? 谢谢

  • 问题是,当我开枪的时候 我如何在本地设置测试的头?(再一次,我不是一个专业人士,我猜当我决定在生产中部署时,我会有相同的起源。如果不是,无论如何,我仍然需要解决方案)

  • 我有一个signar2.0服务器,托管在IIS7中,带有javascript客户端,目前主要针对Chrome浏览器。 在没有跨域的情况下,信号传输是服务器发送的事件,它工作得很好,效率很高。 我使用Microsoft. Owin. Cors以建议的方式向服务器添加了CORS支持——这使服务器与客户端跨域一起工作——但是,SignalR传输现在是长轮询的;这将在我的服务器上造成更高的负载,因为从服务

  • null 我正在尝试使用这个共享对话框在我自己的设备与我自己的Facebook帐户,这是应用程序的管理员以及。 在我的项目中: 项目名称:abddef app_name:Abd Def(在android manifest中)