slxSlashi
slxSlashi

Reputation: 277

AspNetCore.SignalR 2.1 and CORS

I'm migrating our SignalR-Service to the new AspNetCore.SignalR (2.1 preview) and now I get problems with CORS. I will never access the service from the same origin, so I need to disable CORS in general.

I have the folowing CORS policy

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

(My WebApi-Controller calls from a different origin are working fine with these policy)

With the old preview package of SignalR for AspNetCore (AspNetCore.SignalR.Server) I don't got any problems but now, my test client got some http-405 which seems like an issue with CORS.

Is there maybe a extra CORS configuration for SignalR, or do I need to allow something else?

Edit: I created a fresh/clean sample project without any special middleware to check If the error happens here and it does.

Sample WebApplication | startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using WebApplication1.HUBs;

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

        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(
                options => options.AddPolicy("AllowCors",
                    builder =>
                    {
                        builder
                            .AllowAnyOrigin()
                            .AllowCredentials()
                            .AllowAnyHeader()
                            .AllowAnyMethod();
                    })
            );
            services.AddMvc();
            services.AddSignalR(options =>
            {
            });
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors("AllowCors");
            app.UseMvc();
            app.UseSignalR(routes =>
            {
                routes.MapHub<TestHub>("/test");
            });
        }
    }
}

Sample Winforms Application

        private HubConnection _hubConnection;
    private void button1_Click(object sender, EventArgs e)
    {
        var connection = new HubConnectionBuilder().WithUrl("http://localhost:63771/test")
            .WithConsoleLogger()
            .WithTransport(Microsoft.AspNetCore.Sockets.TransportType.WebSockets)
            .Build();
        connection.StartAsync();
    }

Sample Winforms Application ConsoleOutput

fail: Microsoft.AspNetCore.Sockets.Client.HttpConnection[8]
   01/10/2018 15:25:45: Failed to start connection. Error getting negotiation response from 'http://localhost:63771/test'.
System.Net.Http.HttpRequestException: Response status code does not indicate success: 405 (Method Not Allowed).
   bei System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   bei Microsoft.AspNetCore.Sockets.Client.HttpConnection.<Negotiate>d__42.MoveNext()

Upvotes: 20

Views: 17752

Answers (6)

T&#226;n
T&#226;n

Reputation: 1

If you're migrating your project to asp.net core version 3.x, you can upgrade routing from the Configure method like this:

app.UseCors("AllowCors");

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapHub<TestHub>("/test");
});

app.UseMvc and app.UseSignalR will be replaced with app.UseEndpoints. app.UseSignalR also cannot be used anymore because:

This method is obsolete and will be removed in a future version.

Upvotes: 2

Ian Grainger
Ian Grainger

Reputation: 5516

This didn't work for me and a subtly different version did -

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  ...
  app.UseCors(builder => builder
    .AllowAnyHeader()
    .AllowAnyMethod()
    .SetIsOriginAllowed((host) => true)
    .AllowCredentials()
  );

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

Upvotes: 16

slxSlashi
slxSlashi

Reputation: 277

I solved the problem.

The client-package and the server-package were not in the exact subversion state. It was 2.1-preview3210 and 2.1-preview3209 (example numbers).

The server-package is published to the nuget feed frequently but the client-package (npm) not. So I cloned the latest git repo by myself and build the libs and it works.

You will not have the problem anymore, the client-package is now up-to-date.

Upvotes: 1

Peter
Peter

Reputation: 27944

You have to upgrade your package to @aspnet/signalr when upgrading to preview1:

NOTE: Previous previews of the SignalR client library for JavaScript were named @aspnet/signalr-client. This has been deprecated as of Preview 1.

source: Github readme

Upvotes: 1

user9496864
user9496864

Reputation: 154

Try to move app.UseSignalR() on top of app.UseMvc() like this

app.UseCors("AllowCors");
app.UseSignalR(routes =>
    {
        routes.MapHub<TestHub>("/test");
    });
app.UseMvc();

Upvotes: 13

cimbru
cimbru

Reputation: 51

I had the same issue, I use reactjs for clientside. Changing the version from using "@aspnet/signalr-client" into "@aspnet/signalr" solved my problem

Upvotes: 5

Related Questions