简体   繁体   English

asp.net signalr core 中的跨域请求不起作用?

[英]Cross domain request in asp.net signalr core does not work?

I am working on asp.net core signalr 1.1.0 under asp.net core 2.2 version.我正在asp.net core 2.2版本下的asp.net core signalr 1.1.0上工作。 I want to我想要
make the cross-domain request for web client and as well as a mobile client.为 Web 客户端和移动客户端发出跨域请求。 When I send request from javascript client, then this request blocked, and below error shows, (index):1 Access to XMLHttpRequest at ' https://localhost:44373/chatHub/negotiate?token=12 ' from origin ' https://localhost:44381 ' 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'.当我从 javascript 客户端发送请求时,此请求被阻止,并显示以下错误:(index):1 Access to XMLHttpRequest at ' https://localhost:44373/chatHub/negotiate?token=12 ' from origin ' https:// /localhost:44381 ' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:响应中的 'Access-Control-Allow-Origin' 标头的值不能是通配符 '*' 时请求的凭据模式是“包含”。 The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制。

My Javascript client code我的 Javascript 客户端代码

var connection = new signalR.HubConnectionBuilder().withUrl("https://localhost:44373/chatHub?token="+12).build();

Signalr core service startup class code Signalr核心服务启动类代码

 // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder.AllowAnyOrigin()/*WithOrigins("https://localhost:44381")*/
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials());
            });

            services.AddSignalR();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            //services.AddCors();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }


            app.UseHttpsRedirection();
            app.UseCors("CorsPolicy");

            app.UseSignalR(routes =>
            {
                routes.MapHub<ChatHub>("/chatHub");
            });
            //app.UseStaticFiles();
            //app.UseCookiePolicy();
            app.UseMvc();
        }


builder.AllowAnyOrigin() its not working 

builder => builder.WithOrigins(" https://localhost:44381 ") its worked, but this is specific for this origin , I want to make AllowAnyOrigin()?? builder => builder.WithOrigins(" https://localhost:44381 ") 它的工作,但这是特定于这个 origin ,我想让 AllowAnyOrigin()??

I got it working this way我让它以这种方式工作

On Configure services at the top在顶部配置服务

 services.AddCors();

and in the Configure method并在配置方法中

 public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services
    .AddDbContext<ChatContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.Configure<FormOptions>(options =>
            {
                options.MultipartBodyLengthLimit = 60000000;
            });
            services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });

            services.AddMvcCore()
               .AddAuthorization()
               .AddJsonOptions(options =>
               {
                   options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                   options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
               });
            var identityServerAuthOptions = Configuration.GetSection("Identity").Get<IdentityServerAuthenticationOptions>();

            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = identityServerAuthOptions.Authority;
                    options.RequireHttpsMetadata = identityServerAuthOptions.RequireHttpsMetadata;
                    options.ApiName = identityServerAuthOptions.ApiName;
                });


            var settings = new JsonSerializerSettings();
            settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            settings.ContractResolver= new CamelCasePropertyNamesContractResolver();
            services.AddSignalR()
                   .AddJsonProtocol(options => {
                       options.PayloadSerializerSettings = settings;
                          });
            services.AddTransient<IUserService, UserService>();
            services.AddCors();
    }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();
            //Data.AddData(app.ApplicationServices.GetService<ChatContext>());
            app.Use(async (context, next) =>
            {
                if (string.IsNullOrWhiteSpace(context.Request.Headers["Authorization"]))
                {
                    if (context.Request.QueryString.HasValue)
                    {
                        var token = context.Request.QueryString.Value.Split('&').SingleOrDefault(x => x.Contains("authorization"))?.Split('=')[1];
                        if (!string.IsNullOrWhiteSpace(token))
                        {
                            context.Request.Headers.Add("Authorization", new[] { $"Bearer {token}" });
                        }
                    }
                }
                await next.Invoke();
            });
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
              //  app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();
            app.UseAuthentication();
            app.UseCors(x => x.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials());
            app.UseSignalR(config =>
            {

                config.MapHub<UserHub>("/UsersHub");
            });
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
                routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
            });
        }
    }





  app.UseCors(builder =>
            builder.AllowAnyOrigin()
       .AllowAnyMethod()
       .AllowAnyHeader()
           );

Whole code can be found here.整个代码可以在这里找到。 This used to work just fine for me.这曾经对我来说很好用。 I haven't opened it lately though虽然我最近没有打开它

Github Repo Github 仓库

I see two issues with your code.我看到您的代码有两个问题。 Let's tackle them one by one.让我们一一解决它们。

  1. Allowing all origins for the entire application even though you need it only for the SignalR connection.允许整个应用程序的所有来源,即使您只需要它用于 SignalR 连接。 Consider the below code if you want to apply CORS policy only for the signalR endpoint如果您只想对 signalR 端点应用 CORS 策略,请考虑以下代码

     app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<UsersHub>("/UsersHub") .RequireCors((policyBuilder) => policyBuilder .WithOrigins("clientUrls") .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials() });
  2. It is recommended to not allow all origins but if you have such a use case then the below workaround can fix your problem.建议不要允许所有来源,但如果您有这样的用例,那么以下解决方法可以解决您的问题。 This is the trick of using .SetIsOriginAllowed(_ => true)这是使用 .SetIsOriginAllowed(_ => true) 的技巧

     .SetIsOriginAllowed(_ => true) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()

Further if you want more information, have a look at this guide for more details.此外,如果您想了解更多信息,请查看本指南以获取更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM