在要求输入邮箱的文本域,请填写真实的邮件地址。非真实邮件地址,将收不到回复信息。

ASP.NET Core 配置跨域(CORS)

.net core 清风 510℃ 0评论

由于项目中需要实时消息,所以就使用了ASP.NET(Core) SignalR实时通讯库。因为业务服务与通讯服务是独立的,所以涉及到跨域的问题, 浏览器抛出的异常非常明显,这个是明显跨域相关内容。 报错信息如下:

Access to XMLHttpRequest at ‘http://192.168.2.13:5005/api/v1/commommessage/messageHub/negotiate’ from origin ‘http://127.0.0.1:5500’ 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.

CORS(跨域资源共享)是一种W3C标准,允许服务器放宽同源策略。使用CORS,服务器可以在显式允许某些跨域请求时拒绝其他跨域请求。CORS是相比其他跨域技术(比如JSONP)更安全、更灵活。

ASP.NET Core跨域问题需要再 StartUp.cs 文件中进行相关配置。

ConfigureServices方法增加内容

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

完整的ConfigureServices方法示例如下:


        public IServiceProvider ConfigureServices(IServiceCollection services)
        {

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

            services.AddMvc(options => { options.Filters.Add(); })
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                //全局配置Json序列化处理
                .AddJsonOptions(options =>
                {
                    options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                })
                .AddFluentValidation();

            services.AddSignalR();

            return services.AutofacServiceProvider();
        }

在Configure方法中添加

app.UseCors("CorsPolicy");

完整Configure方法示例:


        public void Configure(IApplicationBuilder app, IHostingEnvironment env,
                              ILoggerFactory loggerFactory,
                              IOptions config)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            if (env.IsProduction())
            {
                //注册服务到consul
                app.UseConsul();

                using (HttpClient client = new HttpClient())
                {
                    StringContent content = new StringContent(JsonConvert.SerializeObject(config.Value.RegisterParams));
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                    HttpResponseMessage message = client.PostAsync(config.Value.Server.Address, content).Result;
                };
            }
            app.UseCors("CorsPolicy");
            loggerFactory.AddNLog();
            env.ConfigureNLog("nlog.config");//读取Nlog配置文件
            app.UseSignalR(routes =>
            {
                routes.MapHub("/api/v1/examinations/messageHub");
            });
            app.UseMvc();
        }
特别注意:app.UseCors()必须放在app.UseMvc()之前。

本以为这就算完了,但是万万没想到啊,依然没有什么用。浏览器控制台错误依然存在,.net core也提示了相关警告信息,差点就忘了现在使用.net core 版本和以前不一样了。

The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the policy by listing individual origins if credentials needs to be supported.

目前使用的是ASP.NET CORE 2.1, 其Cors组件已经升级,出于安全考虑必须明确要允许的内容。 这是安全的一部分,你不能这样做。 如果要允许凭据,则Access-Control-Allow-Origin不能使用*。 您必须指定确切的协议+域+端口。

这个问题其实也很好解决,只需要给予一个可信列表即可。修改内容如下:


        services.AddCors(options => options.AddPolicy("CorsPolicy",
            builder =>
            {
                builder.WithOrigins(new string[] { "http://127.0.0.1:5500" })
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();
            }));

如果真的就不想做任何限制,其实也是有办法的。只需要将AllowAnyOrigin替换为SetIsOriginAllowed(_ => true)就可以解决。


       services.AddCors(options => options.AddPolicy("CorsPolicy",
            builder =>
            {
                builder.AllowAnyMethod()
                    .SetIsOriginAllowed(_ => true)
                    .AllowAnyHeader()
                    .AllowCredentials();
            }));

除了前面的两个方法以外,其实还可以自定义中间件。添加Cors处理类。如下:


    public class CorsMiddleware
    {
        private readonly RequestDelegate next;

        public CorsMiddleware(RequestDelegate next)
        {
            this.next = next;
        }
        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Headers.ContainsKey(CorsConstants.Origin))
            {
                context.Response.Headers.Add("Access-Control-Allow-Origin", context.Request.Headers["Origin"]);
                context.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH");
                context.Response.Headers.Add("Access-Control-Allow-Headers", context.Request.Headers["Access-Control-Request-Headers"]);
                context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");

                if (context.Request.Method.Equals("OPTIONS"))
                {
                    context.Response.StatusCode = StatusCodes.Status200OK;
                    return;
                }
            }

            await next(context);
        }
    }

Configure方法中添加如下内容即可。

app.UseMiddleware<CorsMiddleware>();

转载请注明:清风博客 » ASP.NET Core 配置跨域(CORS)

喜欢 (17)or分享 (0)
支付宝扫码打赏 微信打赏
发表我的评论
取消评论

CAPTCHA Image
Reload Image
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址