Laden...

SignalR Selfhosted Call geht nicht durch wegen CORS policy

Erstellt von schuppsl vor 4 Jahren Letzter Beitrag vor 4 Jahren 2.117 Views
S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 4 Jahren
SignalR Selfhosted Call geht nicht durch wegen CORS policy

Hallo zusammen,

mal wieder wende ich mich in letzter Verzweiflung an Euch.
Ich habe einen selfhosted signalR Server (.Net CORE 2.2, Konsole App) aufgesetzt:


using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Features;

namespace SignalR_Server
{
    class SignalR
    {
        public static void StartSignalR()
        {
            var ConsOut = Console.Out;
            Console.SetOut(new StreamWriter(Stream.Null));

            var host = new WebHostBuilder()
                .UseKestrel()
                .UseStartup<Startup>()
                .UseUrls("http://localhost:5050")
                .Build();

            try
            {
                host.Start();
               

            }catch(Exception ex)
            {
                string err = ex.Message;
            }

            Console.SetOut(ConsOut);
        }
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options => options.AddPolicy("CorsPolicy", builder =>
            {
                builder
                    .AllowAnyMethod()
                    .AllowAnyHeader().AllowAnyOrigin();
                    
            }));

            services.AddSignalR();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
            app.UseCors("CorsPolicy");
            app.UseSignalR(route =>
            {
                route.MapHub<MyHub>("/stream");
            });

            
            
        }
    }

    public static class UserHandler
    {
        public static HashSet<string> ConnectedIds = new HashSet<string>();
    }

    public class MyHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
            Console.WriteLine($"User: {user} says {message}");
        }

        public Task SendMessageToCaller(string message)
        {
            return Clients.Caller.SendAsync("ReceiveMessage", message);
        }

        public Task SendMessageToGroups(string message)
        {
            List<string> groups = new List<string>() { "SignalR Users" };
            return Clients.Groups(groups).SendAsync("ReceiveMessage", message);
        }

        public override async Task OnConnectedAsync()
        {
            await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
            UserHandler.ConnectedIds.Add(Context.ConnectionId);
            Console.WriteLine($"Connected user: {Context.ConnectionId}");
            await base.OnConnectedAsync();
        }

        public override async Task OnDisconnectedAsync(Exception exception)
        {
            await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
            UserHandler.ConnectedIds.Remove(Context.ConnectionId);
            Console.WriteLine($"Disconnected user: {Context.ConnectionId}");
            await base.OnDisconnectedAsync(exception);
        }
    }
}



Der Client ist ein reiner JavaScript Client:


...
  <script src="/lib/signalr/dist/browser/signalr.js"></script>
...
const connection = new signalR.HubConnectionBuilder()
    .withUrl("http://localhost:5050/stream")
    .configureLogging(signalR.LogLevel.Information)
    .build();

connection.start().catch(err => console.error(err.toString()));

Rufe ich die HTML Seite mit dem JavaScript auf, meckert der Chrome:

Fehlermeldung:
Access to XMLHttpRequest at 'http://localhost:5050/stream/negotiate' from origin 'https://localhost:44304' 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'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

signalr.js:2430 Error: Failed to complete negotiation with the server: Error
ConsoleLogger.log @ signalr.js:2430
(anonymous) @ signalr.js:2802
step @ signalr.js:2605
(anonymous) @ signalr.js:2586
rejected @ signalr.js:2578
Promise.then (async)
step @ signalr.js:2579
fulfilled @ signalr.js:2577
Promise.then (async)
step @ signalr.js:2579
(anonymous) @ signalr.js:2580
__awaiter @ signalr.js:2576
HttpConnection.getNegotiationResponse @ signalr.js:2773
(anonymous) @ signalr.js:2713
step @ signalr.js:2605
(anonymous) @ signalr.js:2586
step @ signalr.js:2590
(anonymous) @ signalr.js:2586
(anonymous) @ signalr.js:2580
__awaiter @ signalr.js:2576
HttpConnection.startInternal @ signalr.js:2681
HttpConnection.start @ signalr.js:2641
(anonymous) @ signalr.js:1761
step @ signalr.js:1708
(anonymous) @ signalr.js:1689
(anonymous) @ signalr.js:1683
__awaiter @ signalr.js:1679
HubConnection.start @ signalr.js:1750
(anonymous) @ site.js?v=bbSp_ES0ncqX_XK1MVLsTiU7kxXBi9bxmYSw_Kpyug8:11
signalr.js:2430 Error: Failed to start the connection: Error
ConsoleLogger.log @ signalr.js:2430
(anonymous) @ signalr.js:2763
step @ signalr.js:2605
(anonymous) @ signalr.js:2586
rejected @ signalr.js:2578
Promise.then (async)
step @ signalr.js:2579
(anonymous) @ signalr.js:2580
__awaiter @ signalr.js:2576
HttpConnection.startInternal @ signalr.js:2681
HttpConnection.start @ signalr.js:2641
(anonymous) @ signalr.js:1761
step @ signalr.js:1708
(anonymous) @ signalr.js:1689
(anonymous) @ signalr.js:1683
__awaiter @ signalr.js:1679
HubConnection.start @ signalr.js:1750
(anonymous) @ site.js?v=bbSp_ES0ncqX_XK1MVLsTiU7kxXBi9bxmYSw_Kpyug8:11
site.js?v=bbSp_ES0ncqX_XK1MVLsTiU7kxXBi9bxmYSw_Kpyug8:11 Error
(anonymous) @ site.js?v=bbSp_ES0ncqX_XK1MVLsTiU7kxXBi9bxmYSw_Kpyug8:11
Promise.catch (async)
(anonymous) @ site.js?v=bbSp_ES0ncqX_XK1MVLsTiU7kxXBi9bxmYSw_Kpyug8:11

Wie kann ich denn das lösen?

P
441 Beiträge seit 2014
vor 4 Jahren
2.207 Beiträge seit 2011
vor 4 Jahren

Hallo schuppsl,

Emotionen wie "werd irre" gehören nicht in den Titel. Der Titel sollte eine sachliche Problembeschreibung sein.

probier mal

public void ConfigureServices(IServiceCollection services)
{
	// ...
	services.AddCors(options =>
	{
		options.AddPolicy("AllowAllOrigins",
			builder =>
			{
				builder
					.AllowAnyOrigin()
					.AllowAnyHeader()
					.AllowAnyMethod()
					.AllowCredentials();
			});
	});
	// ...
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
	// ...
	app.UseCors("AllowAllOrigins");
	// ...
}

Aber sei dir bewusst, dass du dann von jeder Domain aus Zugriffe mit allen Headern, Methoden etc. zulässt!

Gruss

Coffeebean

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 4 Jahren

Also wenn ich es so mache, geht es:


builder
                    .AllowAnyMethod()
                    .AllowAnyHeader().AllowCredentials().WithOrigins("https://localhost:44304");

Allerdings muss ich den Port explizit mit angeben bei WithOrigins().


WithOrigins("https://localhost")

Funktioniert nicht, dann kommt die Fehlermeldung:

Fehlermeldung:
Access to XMLHttpRequest at 'http://localhost:5050/stream/negotiate' from origin 'https://localhost:44304' 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.

P
441 Beiträge seit 2014
vor 4 Jahren

Das ist korrekt so, der Origin ist eine Kombination aus Protokoll, DNS Name/IP und Port. Deswegen muss alles drei übereinstimmen, sonst kommt diese Fehlermeldung.

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 4 Jahren

Alles klar, vielen Dank Euch allen!
👍