【问题标题】:I set any CORS setting but doesn't work in my ASP.NET Core 5 Web API我设置了任何 CORS 设置,但在我的 ASP.NET Core 5 Web API 中不起作用
【发布时间】:2021-09-20 06:55:29
【问题描述】:

我启用了所有启用 CORS 设置,但其中一些请求方法仍然无法正常工作,例如 Delete、Put。

这是我的代码

public void ConfigureServices(IServiceCollection services)
{
        var appSettings = Configuration.GetSection("ApplicationSettings");

        services.Configure<ApplicationSettingsModel>(Configuration.GetSection("ApplicationSettings"));
        services.AddOptions();
        services.AddControllersWithViews(options => options.UseGeneralRoutePrefix(appSettings.GetValue<string>("apiRoutePrefix") ?? ""));

        services.AddMvc(o => { o.UseGeneralRoutePrefix("api/v{version:apiVersion}"); });
        services.AddApiVersioning(config =>
        {
            config.DefaultApiVersion = new ApiVersion(1, 0);
            config.AssumeDefaultVersionWhenUnspecified = true;
            config.ReportApiVersions = true;
        });
        services.AddOurAuthentication(Configuration);

        services.AddControllers(c => c.Conventions.Add(new ApiExplorerGroupPerVersionConvention()))
        .AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.ContractResolver = new DefaultContractResolver
            {
                NamingStrategy = new CamelCaseNamingStrategy()
            };
        });
        services.AddCors(app =>
        {
            app.AddPolicy("allowAll", a => a.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().SetIsOriginAllowedToAllowWildcardSubdomains());
        });

        if (_enableSwagger)
            services.AddOurSwagger();
}

public void Configure(IApplicationBuilder app)
{
        app.UseDeveloperExceptionPage();
        SwaggerMiddleware(app);
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCors("allowAll");

        app.UseApiResponseAndExceptionWrapper();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(builder => builder.MapControllers());
}

我该如何解决这个问题?

【问题讨论】:

    标签: .net-core cors asp.net-core-webapi


    【解决方案1】:

    我解决了这个问题。 我将代码更改为以下:

    public void ConfigureServices(IServiceCollection 服务) { var appSettings = Configuration.GetSection("ApplicationSettings");

            services.Configure<ApplicationSettingsModel>(Configuration.GetSection("ApplicationSettings"));
            services.AddOptions();
            services.AddControllersWithViews(options => options.UseGeneralRoutePrefix(appSettings.GetValue<string>("apiRoutePrefix") ?? ""));
    
            services.AddMvc(o => { o.UseGeneralRoutePrefix("api/v{version:apiVersion}"); });
            services.AddApiVersioning(config =>
            {
                config.DefaultApiVersion = new ApiVersion(1, 0);
                config.AssumeDefaultVersionWhenUnspecified = true;
                config.ReportApiVersions = true;
            });
            services.AddOurAuthentication(Configuration);
    
    
            services.AddControllers(c => c.Conventions.Add(new ApiExplorerGroupPerVersionConvention()))
            .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new DefaultContractResolver
                {
                    NamingStrategy = new CamelCaseNamingStrategy()
                };
            });
          
            services.AddCors(options =>
            {
                options.AddPolicy("allowAll",
                    builder => builder
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .SetIsOriginAllowed(s => true)
                        .SetPreflightMaxAge(TimeSpan.FromMinutes(9))
                        .AllowCredentials()
                        .Build());
            });
    
            if (_enableSwagger)
                services.AddOurSwagger();
    
    
        }
        public void Configure(IApplicationBuilder app)
        {
            app.UseDeveloperExceptionPage();
            SwaggerMiddleware(app);
         //   app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
    
            app.UseAuthentication();
            app.UseAuthorization();
    
            app.UseCors("allowAll");
            app.UseCorsMiddleware();
            // app.UseApiResponseAndExceptionWrapper();
    
            app.UseEndpoints(builder => builder.MapControllers());
        }
    

    还有这段代码:

     public class CorsMiddleware
        {
            private readonly RequestDelegate Next;
            public CorsMiddleware(RequestDelegate next)
            {
                Next = next;
            }
            public Task Invoke(HttpContext context)
            {
                return BeginInvoke(context);
            }
            private Task BeginInvoke(HttpContext context)
            {
                context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
                context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept, Athorization, ActualUserOrImpersonatedUserSamAccount, IsImpersonatedUser" });
                context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" });
                if (context.Request.Method == HttpMethod.Options.Method)
                {
                    context.Response.StatusCode = (int)HttpStatusCode.OK;
                    return context.Response.WriteAsync("OK");
                }
                return Next.Invoke(context);
            }
        }
    
        // Extension method used to add the middleware to the HTTP request pipeline.
        public static class CorsMiddlewareExtensions
        {
            public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
            {
                return builder.UseMiddleware<CorsMiddleware>();
            }
        }
    

    【讨论】:

      【解决方案2】:

      您必须在启动时更改 Cors 代码的位置。将此代码放在 ConfigureServices 的顶部

        public void ConfigureServices(IServiceCollection services)
              {
                  services.AddCors(o => o.AddPolicy("AllowAnyOrigins", builder =>
                  {
                             builder.AllowAnyOrigin()
                             .AllowAnyMethod()
                             .AllowAnyHeader();
                  }));
      
                 ........... 
                  
              }
      

      app.UseCors 应该放在 app.UseRouting() 和 app.UseAuthorization() 之间

         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
         {
                  .....
      
                  app.UseRouting();
      
                  app.UseCors("AllowAnyOrigins");
      
                  app.UseAuthentication();
                 app.UseAuthorization();
      
                  ....
            }
      

      【讨论】:

        【解决方案3】:

        从评论建议中编辑,删除 AllowCredentials 我注意到 OP 在他的代码中没有这个。

        试试这个,而不是创建一个策略,如果你这样做了会怎样:

        app.UseCors(x => x
             .AllowAnyMethod()
             .AllowAnyHeader()
             .SetIsOriginAllowed(origin => true)); // allow any origin
        

        如果这有效,那是因为您正在创建一个策略,而该策略可能没有应用。但以上内容应该在没有政策的情况下工作。

        您还提到只有某些动词不起作用 - cors 错误可能掩盖了 500 异常,测试的方法是,如果出现 500(或其他)异常,您的代码实际上会被命中,所以你可以用断点测试它,如果你的断点被命中,即使浏览器这么说,它也不是 CORS。

        但很可能您正在创建一个策略,而不是将该策略应用于不起作用的事物。上面的代码是全局的。

        【讨论】:

        • 不!您允许所有具有凭据的来源,这相当于放弃整个同源政策。您的建议非常不安全。
        • @jub0bs 我明白了,但他已经在他的代码示例中使用了该逻辑,我只是​​将他自己的代码重新格式化为全局代码(至少我认为!)
        • @jub0bs 好机会问你,我确实将这种类型的东西用于面向公众的移动应用程序,除了在亚马逊中使用 API 网关模式,我不确定我是否有很多选择吗?
        • 我使用 .WithMethods("GET,POST,DELETE,PUT,OPTIONS"),但不起作用
        • @mosi98 .Withmethods 不会做任何事情,因为您已经指定了 AllowAnyMethod。
        猜你喜欢
        • 2021-09-03
        • 2017-09-29
        • 2015-05-05
        • 1970-01-01
        • 1970-01-01
        • 2016-10-14
        • 1970-01-01
        • 2017-12-25
        • 2022-07-07
        相关资源
        最近更新 更多